过滤器就是用来过滤的
过滤器既可以浏览器发送给服务器的请求(有一些请求是垃圾请求,不需要处理)
也可以过滤服务器发送给浏览器的响应(有时候响应是乱码,应该先转码再发送给浏览器)
在访问web资源之前,可以对浏览器发给tomcat服务器的请求要求进行检查
在访问web资源之后,也可以对tomcat服务器发给浏览器的响应进行检查
代码实现过滤器机制:(通过过滤器解决请求和响应的乱码问题)
新建一个类,实现Filter过滤器接口
public class CharacterEncodingFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
//给请求和响应设置编码格式,这样就不会乱码了
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//这行代码是固定的代码,必须写这行代码
chain.doFilter(request,response);//让我们的请求继续走,如果不写,程序到这里就被拦截停止了
}
@Override
public void destroy()
{
Filter.super.destroy();
}
}
在web.xml中进行注册
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.kuang.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--/*表示在浏览器中输入任何路径都会先经过这个过滤器-->
<url-pattern>/*</url-pattern>
</filter-mapping>
这时侯所有的请求和响应都会先走一遍过滤器
利用过滤器实现:用户登录之后才能进入主页,用户注销之后就不能进入主页
(1)登录成功跳转到登陆成功的页面,登陆失败跳转到登录失败的页面
public class LoginServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//获取请求中的username这个key的value
String username=request.getParameter("useename");
if(username.equals("admin")//登录成功
{
//登陆成功就把用户信息放到session里面
request.getSession().setAttribute("USER_SESSION",request.getSession().getId());
//登陆成功就跳转到登陆成功的页面
response.sendRedirect("/sys/success.jsp");
}
else//登录失败
{
//登陆失败就跳转到登陆失败的页面
response.sendRedirect("/sys/fail.jsp");
}
}
}
(2)退出账号
public class LogoutServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Object user_session=request.getSession().getAttribute("USER_SESSION");
//如果session里USER_SESSION这个key的value不为空,说明用户登录成功了,把value值清空了,用户就退出登录了
if(user_session!=null)
{
request.getSession().removeAttribute("USER_SESSION");
//重定向到登录页面
response.sendRedirect("/Login.jsp");
}
}
}
通过过滤器可以对服务器管理的所有 Web 资源(例如 JSP、Servlet、静态 HTML 文件、静态图片等)进行拦截,从而实现一些特殊的功能,例如用户的权限控制、过滤敏感词、设置统一编码格等。
- 客户端请求访问容器内的 Web 资源。
- Servlet 容器接收请求,并针对本次请求分别创建一个 request 对象和 response 对象。
- 请求到达 Web 资源之前,先调用 Filter 的 doFilter() 方法,检查 request 对象,修改请求头和请求正文,或对请求进行预处理操作。
- 在 Filter 的 doFilter() 方法内,调用 FilterChain.doFilter() 方法,将请求传递给下一个过滤器或目标资源。
- 目标资源生成响应信息返回客户端之前,处理控制权会再次回到 Filter 的 doFilter() 方法,执行 FilterChain.doFilter() 后的语句,检查 response 对象,修改响应头和响应正文。
- 响应信息返回客户端。
部署多个 Filter,若这些 Filter 都拦截同一目标资源,则它们就组成了一个 Filter 链(也称过滤器链)。过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到传递给目标资源。
另一个例子:
效果:打开浏览器访问http://localhost:8080/test1?name=cc,结果返回success字符串
而控制台中打印了:只获取第一个key:value对,第二个第三个不获取
请求的参数名字:name
请求的值:[cc]
@ResponseBody
@GetMapping("/test1")
public String test1(){
return "success";
}
public class MyHttpFilter implements Filter
{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
//获取访问的url
HttpServletRequest servletRequest=(HttpServletRequest) servletRequest;
String requestUrl= servletRequest.getRequestURI();
//如果访问路径时localhost:8080/test1,那说明这个请求就是我们要拦截的对象
if(requestUrl.equals("/test1"))
{
Map map=servletRequest.getParameterMap();
for(entry:map.entrySet())
{
System.out.println("请求的参数名字是:"+entry.getKey());
System.out.println("请求的值是:"+entry.getValue());
return;
}
}
//放行,继续处理后面的业务
filterChain.doFilter(servletRequest,servletResponse);
}
}