9.Servlet与过滤器
初识Servlet
- Servlet做了什么?
- 本身不做任何业务处理
- 只是接收请求并决定调用哪个JavaBean去处理请求
- 确定用哪个页面来显示处理返回的数据
- Servlet是什么?
- Server+Applet,是一种服务器端的Java应用程序
- 只有当一个服务器端的程序使用了Servlet API的时候,这个服务端
- 的程序才能称之为Servlet
- JSP与Servlet之间的关系
- Servlet是运行在服务器端的Java应用程序
Servlet API
- 主要Servlet API介绍
- javax.servlet.Servlet接口
- 所有Java Servlet的基础接口类,规定了必须由Servlet具体类实现的方法集
- javax.servlet.GenericServlet类
- 是Servlet的通用版本,是一种与协议无关的Servlet
- javax.servlet.http.HttpServlet类
- 在GenericServlet基础上扩展的基于Http协议的Servlet
- 如何创建Servlet
- 实现Servlet接口
- 继承GenericServlet类
- 继承HttpServlet类
Servlet
- Servlet中主要方法
init()
:Servlet的初始化方法,仅仅会执行一次service()
:处理请求和生成响应destroy()
:在服务器停止并且程序中的Servlet对象不再使用的时- 候调用,只执行一次
- ServletRequest
- 封装客户的请求信息
- 作用相当于JSP内置对象request
- ServletResponse
- 创建响应信息,将处理结果返回给客户端
- 作用相当于JSP内置对象response
- ServletConfig
- 包含了Servlet的初始化参数信息
Servlet生命周期
- Servlet生命周期各个阶段
- 加载和实例化
- 初始化
- 处理请求
- 销毁
生命周期 | 谁来做 | 何时做 |
---|---|---|
实例化 | Servlet 容器 | 当Servlet容器启动或者容器检测到客户端请求时 |
初始化 | Servlet 容器 | 实例化后,容器调用Servlet的init()初始化对象 |
处理请求 | Servlet 容器 | 得到客户端请求并做出处理时 |
销毁 | Servlet 容器 | 当程序中的Servlet对象不再使用的时候, 或者Web服务器停止运行的时候 |
部署运行Servlet
Servlet部署与运行
- 修改web.xml(部署描述文件)
- 添加< servlet >:把Servlet内部名映射到一个Servlet类名
- 添加< servlet-mapping >:把用户访问的URL映射到Servlet的内部名
注意:
<servlet-mapping>与<servlet>中的<servlet-name>必须一致
- 通过URL访问Servlet
Servlet配置
配置Servlet
- 配置< servlet >元素
<servlet> <servlet-name>myServlet3</servlet-name> <servlet-class>demo.web.servlet.MyServlet3</servlet-class> </servlet> /* myServlet3: Servlet名称唯一 demo.web.servlet.MyServlet3: Servlet类所在路径 */
- 配置 < servlet-mapping >元素
<servlet-mapping> <servlet-name>myServlet3</servlet-name> <url-pattern>/myServlet3</url-pattern> </servlet-mapping> /* myServlet3: 与<servlet>的<servlet-name>设置相同 /myServlet3: 访问Servlet的URL,相对于Web应用的路径,有三种配置方式 */
初始化参数设置
- 配置< init-param >元素
<servlet>
……
<init-param>
<param-name>charSetContent</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
/*
charSetContent: 参数名称
utf-8: 参数值
*/
public void init(ServletConfig config) throws ServletException {
String initParam=config.getInitParameter("charSetContent"); //通过ServletConfig对象读取初始化参数
System.out.println(initParam);
}
代码示例
LoginServlet.java
package com.r.servlet;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.r.pojo.User;
import com.r.service.UserService;
import com.r.service.impl.UserServiceImpl;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet") //用来访问此servlet的路径
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置网页字符编码集
response.setContentType("text/html;charset=utf-8");
//设置接收参数
String ucode = request.getParameter("ucode");
String upwd = request.getParameter("upwd");
UserService us = new UserServiceImpl();
User user = new User();
user = us.login(ucode, upwd);
if(user != null){
String uname = user.getUserName();
request.setAttribute("ucode",ucode);
request.setAttribute("uname",uname);
//设置Cookie
//如果Cookie中值存在中文,就将其编码设置成utf-8(也可能因为设置了反而乱码,看具体情况)
String usercode = URLEncoder.encode(ucode, "utf-8");
Cookie cookie = new Cookie("usercode",usercode);
//设置路径为根目录(方便使用)
cookie.setPath("/");
//设置cookie生命周期
cookie.setMaxAge(20); //s
//添加cookie(response)
response.addCookie(cookie);
Cookie cookie1 = new Cookie("upwd",upwd);
//设置路径为根目录(方便使用)
cookie1.setPath("/");
//设置cookie生命周期
cookie1.setMaxAge(20); //s
//添加cookie(response)
response.addCookie(cookie1);
//创建session
HttpSession session = request.getSession();
//存入用户session
session.setAttribute("uname", uname);
//设置session过期时间
session.setMaxInactiveInterval(60 * 60);
response.sendRedirect("web/ProviderAllServlet");
} else {
response.sendRedirect("/login.jsp");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
过滤器
- 过滤器
- 是向Web应用程序的请求和响应添加功能的Web服务组件
- 过滤器可以统一地集中处理请求和响应
- 使用过滤器技术实现对请求数据的过滤
使用步骤
过滤器的使用步骤
- 建立实现javax.servlet.Filter接口的类,实现过滤行为
doFilter(...) { //过滤请求 chain.doFilter(request, response); //调用下一个过滤器或Web资源 //过滤响应 }
- 在web.xml中配置过滤器
<filter>
<filter-name>过滤器名</filter-name>
<filter-class>过滤器的完全限定名</filter-class>
</filter>
<filter-mapping>
<filter-name>过滤器名</filter-name>
<url-pattern>过滤器映射的Web资源</url-pattern>
/*
完全匹配:/index.jsp
目录匹配:/admin/*
扩展名匹配:*.do
全部匹配:/*
*/
</filter-mapping>
示例
用于全局项目编码
CharEncodingFilter.java
package com.r.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* 过滤项目编码
* Servlet Filter implementation class CharEncodingFilter
*/
@WebFilter("/*") //需要过滤的路径,/*为整个项目
public class CharEncodingFilter implements Filter {
/**
* Default constructor.
*/
public CharEncodingFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
//设置网页字符编码集
response.setContentType("text/html;charset=utf-8");
// pass the request along the filter chain
chain.doFilter(request, response); //放行
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
简单的登录过滤
LoginFilter.java
package com.r.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet Filter implementation class LoginFilter
*/
@WebFilter("/web/*")
public class LoginFilter implements Filter {
/**
* Default constructor.
*/
public LoginFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
//判断session是否为空
HttpServletRequest req = (HttpServletRequest)request;
if (req.getSession().getAttribute("uname") != null) {
// pass the request along the filter chain
chain.doFilter(request, response); //放行
} else {
HttpServletResponse res = (HttpServletResponse)response;
res.sendRedirect(req.getContextPath() + "/login.jsp");
}
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
注:在这里使用request或response需要强转,因为servlet的方法参数和filter的方法参数不同(子父类关系)
过滤器的生命周期
- 实例化
- 初始化:
init()
- 过滤:
doFilter()
- 销毁:
destroy()
初始化参数
- 配置过滤器的初始化参数
- 配置< init-param >元素
<filter>
<init-param>
<param-name>Encoding</param-name> <!-- 参数名称 -->
<param-value>UTF-8</param-value> <!-- 参数值 -->
</init-param>
</filter>
- 读取过滤器的初始化参数
init(FilterConfig fConfig) {
String encoding=fConfig.getInitParameter("Encoding"); //通过FilterConfig对象读取初始化参数
}
过滤器链
- 多个过滤器会形成过滤器链。根据过滤器的配置,按照先后顺序执行
过滤器的应用场合
- 对请求和响应进行统一处理
- 对请求进行日志记录和审核
- 对数据进行屏蔽和替换
- 对数据进行加密和解密