Servlet基础知识(自学笔记)
使用工具:intellij idea2018版
需准备:
(1)安装intellij idea
(2)安装jdk
(3)安装Tomcat
(4)可以在创建工程之前配置好环境,也可以如下视频在创建过程中配置
1.servlet的简单介绍
servlet全称java Servlet,是用java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态web内容。是JavaWeb的三大组件之一(Filter和Listener)
作用:接受客户端发来的请求数据,处理数据,将处理结果通过响应发送给客户端
2.servlet的两种创建方式
(1)servlet3.0之前,通过web.xml部署描述文件,如下视频
第一个servlet.mp4
(2)servlet3.0之后,可以通过注解的方式创建,详细步骤基本同上,区别如下:
a. 在new时选择servlet,然后输入名字即可
b.不用web.xml文件部署,在开头部署,如下标识
剩下的操作和视频1中是基本一样的。
3.request与response
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
@WebServlet(name = "RequestServlet",urlPatterns = "/request")
public class RequestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("接收到get请求");
//请求行
System.out.println("请求方式:"+request.getMethod());
System.out.println("URI:"+request.getRequestURI());
System.out.println("发出请求客户端IP地址:"+request.getRemoteAddr());
System.out.println("服务点请求的IP地址:"+request.getLocalAddr());
System.out.println("访问客户端的端口号"+request.getRemotePort());
System.out.println("web应用路径:"+request.getContextPath());
System.out.println("http协议和版本:"+request.getProtocol());
//获取请求头所有属性信息
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
String element = headerNames.nextElement();
System.out.println(element+":"+request.getHeader(element));
}
//请求体,获取请求参数内容
String name = request.getParameter("name");
String passWord = request.getParameter("passWord");
System.out.println("用户名:"+name);
System.out.println("密码:"+passWord);
//检验登陆状态方式1
String result="登陆成功!";
// ServletOutputStream outputStream = response.getOutputStream();
// outputStream.write(result.getBytes());
//检验登陆状态方式2
response.setContentType("text/html;charset=utf-8");//没有设置这个编码格式,有可能输出结果是乱码
PrintWriter writer = response.getWriter();
writer.write(result);
}
}
使用的html文件:action的request对应 urlPatterns = "/request",意思是当点击提交按钮时,RequestServlet的数据请求可以接收到表单提交的数据
<html>
<head>
<title>get请求表单</title>
</head>
<body>
<center>
<h2>发起http get请求</h2>
<form action="request" method="get">
<p>账号:<input type="text" name="name" /></p>
<p>密码:<input type="text" name="passWord" /></p>
<input type="submit" name="提交" />
</form>
</center>
</body>
</html>
4.验证码切换
package com.study.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(name = "VerifyCodeServlet",urlPatterns = "/code")
public class VerifyCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width=100;
int height=30;
//定义随机字符
String data="abcdefghijklmnopqrstuvwxyz0123456789";
//创建随机对象
Random random = new Random();
//创建图片流
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
//设置图片背景色及形状
Graphics graphics = image.getGraphics();
graphics.setColor(Color.gray);
graphics.fillRect(0,0,width,height);
//设置随机字符数量和颜色、位置及字符
graphics.setColor(Color.black);
for(int i=0;i<4;i++){
int position=random.nextInt(data.length());
String substring = data.substring(position, position + 1);
graphics.drawString(substring,width/5*(i+1),15);
}
//输出请求
ImageIO.write(image,"jpg",response.getOutputStream());
}
}
jsp文件
<%--
Created by IntelliJ IDEA.
User: shinelon
Date: 2020/11/23
Time: 10:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>验证码</title>
</head>
<body>
<center>
<h2>切换验证码</h2>
<script>
function changeImageCode() {
document.getElementById('btn').isDisable=true;
document.getElementById('identity').src='code?ts='+new Date().getTime();
}
</script>
<img src="code" id="identity" onload="btn.disable=false;" style="cursor: pointer;vertical-align: center" />
<input type="button" value="看不清,更换验证码" onclick="changeImageCode()" id="btn" style="vertical-align: center" />
</center>
</body>
</html>
5.servlet的声明周期
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* servlet是单例设计模式
* 无论多少次请求都是只有一个servlet实例
* 多个客户端并发时,服务器则会启动多个线程分别执行servlet的service方法
*/
@WebServlet(name = "LifeServlet", urlPatterns = "/life")
public class LifeServlet extends HttpServlet {
@Override
public void init() throws ServletException {//启动服务器,执行该servlet请求只会会执行一次
System.out.println("初始化过程.....");
}
//每次请求都会调用
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("服务过程中.....");
doGet(req,resp);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doget调用中.....");
}
//关闭服务器调用
@Override
public void destroy() {
System.out.println("销毁中.....");
}
}
6.servletConfig和servletContext
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* servlet是单例设计模式
* 无论多少次请求都是只有一个servlet实例
* 多个客户端并发时,服务器则会启动多个线程分别执行servlet的service方法
*/
@WebServlet(name = "LifeServlet", urlPatterns = "/life")
public class LifeServlet extends HttpServlet {
@Override
public void init() throws ServletException {//启动服务器,执行该servlet请求只会会执行一次
System.out.println("初始化过程.....");
}
//每次请求都会调用
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("服务过程中.....");
doGet(req,resp);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doget调用中.....");
}
//关闭服务器调用
@Override
public void destroy() {
System.out.println("销毁中.....");
}
}
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "HelloServlet1",urlPatterns = "/Get")
public class HelloServlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("发送请求");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("get请求");
//获取HelloServlet的发送对象name
System.out.println(this.getServletContext().getAttribute("name"));
}
}
7.登陆验证及转发
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 请求转发,发送到错误页面
*/
@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userName="preston";
String userPassWord="123456";
//获取登陆页面信息
String name = request.getParameter("name");
String passWord = request.getParameter("passWord");
//判断
if(!name.equals(userName)){
request.setAttribute("errorMessage","用户名错误");//发送错误信息
request.getRequestDispatcher("/loginError.jsp").forward(request,response);//转发
}else if(!passWord.equals(userPassWord)){
request.setAttribute("errorMessage","密码错误");//发送错误信息
request.getRequestDispatcher("/loginError.jsp").forward(request,response);//转发
}else{
//重定向方法1
// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
// response.setHeader("Location","https://www.baidu.com/");
//重定向方法2
// response.sendRedirect("https://www.baidu.com/");
//跳向自己写的首页
response.sendRedirect("/hello/index.jsp");
}
}
}
8.线程安全
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 线程安全问题:
* 尽量少用成员变量
*
*/
@WebServlet(name = "ThreadServlet",urlPatterns = "/thread")
public class ThreadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int a=0;
//5秒之后才输出结果
synchronized (this){
a++;
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(a+"");
}
}
}
9.读取配置文件db.properties
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 读取配置文件db.properties
*/
@WebServlet(name = "ReadDatabaseServlet",urlPatterns = "/data")
public class ReadDatabaseServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/db.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
String name = properties.getProperty("name");
String passWord = properties.getProperty("passWord");
String url = properties.getProperty("url");
System.out.println(name);
System.out.println(passWord);
System.out.println(url);
}
}
db.properties文件
name=preston
passWord=50095
url=baidu.com
10.自动刷新功能
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自动刷新
*/
@WebServlet(name = "RefreshServlet",urlPatterns = "/refresh")
public class RefreshServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**另一种自动刷新方式
* <meta http-equiv='refresh' content='3;url='>固定格式
*/
String message="<meta http-equiv='refresh' content='3;url=/hello/index.jsp'>3秒后会自动跳转到首页,如果没有跳转,请点击<a href='/hello/index.jsp'>跳转连接</a>";
request.setAttribute("message",message);
request.getRequestDispatcher("/index.jsp").forward(request,response);
}
private void request() {
// response.setContentType("text/html;charset=utf-8");
//自动刷新
// response.setHeader("refresh","3");
// response.getWriter().print("3秒后自动刷新");
//3秒后跳转到指定网页
// response.setHeader("refresh","3;url='/hello/index.jsp'");
// response.getWriter().print("3秒后自动刷新");
}
}
11.文件下载
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@WebServlet(name = "DownloadServlet",urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//压缩文件直接下载,其它直接打开
//response.getWriter();//输出字节码文件
String filename = request.getParameter("filename");
//通知浏览器不要预览,直接下载
String type = this.getServletContext().getMimeType(filename);
response.setContentType(type);
//通知浏览器下载的方式
response.setHeader("Content-Disposition","attachment;filename="+filename);
//获取文件的绝对路径
String realPath = this.getServletContext().getRealPath("download/"+filename);
InputStream in = new FileInputStream(realPath);
ServletOutputStream outputStream = response.getOutputStream();//输出二进制文件
//文件拷贝
int len=0;
byte[] buffer=new byte[1024];
while ((len=in.read(buffer))>0){
outputStream.write(buffer,0,len);
}
in.close();
}
}
综合实例链接:https://mp.csdn.net/console/editor/html/110004445