Servlet是Java提供的一门动态的web资源开发技术
Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servelt
Servlet快速入门
- 创建web项目,导入Servlet依赖坐标
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
2.创建一个类实现Servlet接口,并重写接口中的所有方法,并在service方法中输出一句话
3.配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("/demo")
public class ServletImpl implements Servlet {
4.访问:启动Tomcat,浏览器URL范围访问Servlet
Servlet执行流程
Http://localhost:8080访问的是web服务器
由web服务器创建Servlet对象,Servlet方法由web服务器调用
Servlet生命周期
Servlet运行在web服务器中,其生命周期由web服务器管理
- 加载和实例化:默认情况下,当Servlet第一次被访问的时候,web服务器会创建Servlet对象
@WebServlet(loadOnStartup=1)
//负整数:第一次被访问的时候创建Servlet实例
//0或者正整数:服务器启动的时候就会创建Servlet实例
2.初始化:在Servlet实例化之后,web服务器将调用Servlet的init()方法初始化这个对象,完成一些加载配置文件,创建连接等初始化工作,该方法只调用一次
3.请求处理:每次请求Servlet时,web服务器都会调用Servlet的service方法对请求进行处理
4.服务终止:当需要释放内存或者关闭web服务器时,web服务器会调用Servlet对象的destory()方法完成资源的释放。在destory()方法调用之后,web服务器会释放Servlet这个实例,该实例会被Java的垃圾回收器进行回收
Servlet体系结构
get和post请求方式的请求消息不一样,所以要分开处理,根据不同的请求方式,调用不同的逻辑
Servlet urlPattern配置
Servlet想要被访问,必须配置其访问路径
- 一个Servlet可以配置多个访问路径
@WebServlet(urlPattern={"/demo1","/demo2"})
URL匹配规则
- 精确匹配
//配置路径
@WebServlet(urlPattern={"/user/select"})
//访问路径
localhost:8080/web-demo/user/select
2.目录匹配
//配置路径
@WebServlet(urlPattern="/user/*")
//访问路径
localhost:8080/web-demo/user/aaa
localhost:8080/web-demo/user/bbb
3.扩展名匹配
//配置路径
@WebServlet(urlPattern="*.is")
//访问路径
localhost:8080/web-demo/aaa.is
localhost:8080/web-demo/bbb.is
4.任意匹配
//配置路径
@WebServlet(urlPattern="/")
@WebServlet(urlPattern="/*")
//访问路径
localhost:8080/web-demo/hehe
localhost:8080/web-demo/haha
Request和Response
Request:获取请求数据
Response:设置响应数据
Request
Request的继承体系
Tomcat需要解析请求数据,封装为Request对象并且创建request对象传递到service方法中
Request获取请求数据
请求数据分为三部分
- 请求体
- String getMethod():获取请求方式
- String getContextPath():动态获取虚拟目录
- StringBuffer getRequestURL():获取URL
- String getRequestURI():获取URI
- String getQueryString():获取请求参数
2 .请求头
- String getHeader():根据请求头名称,获取值
3.请求体
- ServletInputStream getInputStream:获取字节输入流
- BufferedReader getReader():获取字符输入流
Request通用方式获取请求参数
GET请求方式和POST请求方式主要是在于获取请求参数的不同,提供一种统一获取请求参数的方法,从而减少代码的重用率
- Map<String,String[]> getParameterMap():获取所有参数Map集合
- String[] getParameterValues(String name):根据名称获取参数值(数组)
- String getParameter(String name):根据名称获取参数值(单个值)
POST请求方式解决中文乱码问题
POST请求方式获取请求参数是通过字符输入流进行获取,字符输入流的默认字符集是ISO字符集
request.setCharacterEncoding("UTF-8")
GET请求方式解决中文乱码问题
GET请求方式获取请求参数是通过getQueryString()方法进行获取
GET请求先通过浏览器进行编码使用的是UTF-8字符集,然后通过Tomcat服务器进行解码,使用的是ISO字符集,编码和解码的字符集不同,所以会导致乱码
要正确解码应该把编码之后的数据转换成二进制数据,再把二进制数据转为字符串
POST方式也可以用这个方式,但是用设置字符集的方式更方便
String encode = URLEncoder.encode("张三","UTF-8")
String decode = URLDecoder.decode(encode,"IOS-8859-1")
//转换成字节数据 编码
byte[] bytes = decode.getBytes("ISO-8859-1")
//转换成字符串 解码
String str = new String(bytes,"UTF-8")
//转换成一行
String username = request.getparamter("username")
username = new String(username.getBytes(StandardCharsets.IOS-88859-1),StandardCharsets.UTF-8)
Request请求转发
请求转发:再服务器内部进行资源跳转的方式
在资源a中写请求转发的代码
request.getRequestDispatcher("资源b的路径").forward(request,response)
请求转发资源间共享数据,使用Request对象
- void setAttribute(String name,Object o):存储数据到request域中
- Object getAttribute(String key):根据key,获取值
- void removeAttribute(String key):根据key,删除键值对
请求转发的特点:
- 浏览器地址不会发生变化
- 只能转发到当前服务器的内部资源
- 一次请求,可以在转发的资源间使用request共享数据
Response
Response的继承结构
Tomcat创建response对象并传入service方法中
Response设置响应数据
响应数据分为三部分
- 响应行
void setStatus(int sc)//设置响应码
2.响应头
void setHeader(String name,String value)//设置响应数据键值对
3.响应体
PrintWriter getWriter()//获取字符输出流
ServletOutputStream get OutputStream()//获取字节输出流
Response重定向
重定向:是一种资源跳转的方式
浏览器先请求资源a,资源a处理不了,设置一个状态码302,然后再设置响应头给浏览器,浏览器对着响应头再请求对应的资源b
response.setStatus(302)
response.setHeader("location","资源b的路径")
//简化方式完成重定向
response.sendRedirect("资源b的路径")
重定向的特点
- 浏览器的地址栏会发生改变
- 可以重定向到任意资源
- 两次请求,不能在多个资源下使用request共享数据
路径问题
判断路径给谁使用,如果路径要给浏览器使用需要加虚拟目录,如果路径要给服务端使用就不需要加虚拟目录
动态获取虚拟目录
String contextPath = resp.getContextPath()
Response响应字符数据
- 获取字符输出流
PrintWriter writer = response.getWriter()
2.设置响应头信息
response.serHeader("content-type","text/html")
3.写到浏览器数据
//解决中文乱码问题
response.setContentType("text.html;charset=utf-8");
writer.write("你好");
字符输出流不需要关闭,随着响应结束,response对象被销毁,流也就关闭了
Response响应字节数据
- 读取文件
FileInputStream fis = new FileInputStream("")
2. 获取字节输出流
ServletOutputStream os = response.getOutputStream
3. 完成文件的拷贝
//使用apache提供的工具类IOUtils的工具类
IOUtils.cpoy(fis,os)
4.关闭流
fis.close()