Filter过滤器
过滤器的生命周期:
在服务器启动的时候,过滤会进行实例化(1次,调用构造方法)和初始化(1次,调用init())
客户端发送请求会执行doFilter()
过滤器销毁时会调用destroy方法
多个过滤器,实例化和初始化的循序跟web.xml的配置顺序无关
过滤方法的执行顺序是跟web.xml配置有关 – 先配置的先过滤后结束
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.qf.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.qf.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如上配置过滤顺序为:
EncodingFilter过滤
LoginFilter过滤
LoginFilter过滤结束
EncodingFilter过滤结束
创建一个过滤器
写一个抽象类实现Filter
package com.qf.filter;
import javax.servlet.*;
/**
* @author nyh
* @create 2019-02-26 10:43
**/
public abstract class DefaultFilter implements Filter {
public void destroy() {
System.out.println("销毁过滤器");
}
public void init(FilterConfig config) throws ServletException {
System.out.println("初始化过滤器");
}
}
然后继承这个抽象类就可以了
这样写的好处就是不用每个过滤器都实现destroy(),init()
方法,我们只关注doFilter()
方法就好了
public class LoginFilter extends DefaultFilter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//转为功能更为强大的HttpServlet
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
//出问题最好打印一下URI
String requestURI = req.getRequestURI();
//放行
filterChain.doFilter(req, resp);
}
}
过滤器能用来避免用户访问未授权的页面
${msg}
<form action="LoginServlet">
<input type="hidden" name="action" value="login">
用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"><br/>
<input type="submit" value="登录">
</form>
public class LoginFilter extends DefaultFilter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//获取的是请求的相对路径
String uri = req.getRequestURI();
System.out.println(uri);
String username = (String)req.getSession().getAttribute("username");
// 判断是否访问login.jsp页面 是则放行 不是则进行判断用户是否登录
if(uri.endsWith("login.jsp") || uri.endsWith("LoginServlet")){
chain.doFilter(req,resp);
}else{
if(username == null || "".equals(username)){
resp.sendRedirect("login.jsp");
}else{
//放行
chain.doFilter(req,resp);
}
}
}
}
编码过滤器
第一种,直接在Tomcat的配置文件server.xml中配置
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
不推荐,可能公司不让你直接改服务器配置文件
第二种:编码过滤器
处理请求乱码问题
比如你从请求中取值String username = request.getParameter("username");
然后你发现这个值username
乱码了,这个时候你就可以用编码过滤器解决问题了
或者你String username = new String(username.getBytes("iso-8859-1"),"utf-8");
直接这样每个都转一下也可以
从根源解决问题,重写request.getParameter(),使getParameter里面对请求的数据进行乱码处理
在过滤器中创建MyHttpServletRequest
类继承HttpServletRequestWrapper
类(这个类实现了HttpServletRequest
)
重写MyHttpServletRequest
的getParameter()
package com.qf.filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* @author nyh
* @create 2019-02-26 10:44
**/
public class LoginFilter extends DefaultFilter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
//处理post请求的编码问题
req.setCharacterEncoding("utf-8");
//处理响应的编码问题
resp.setContentType("text/html;charset=utf-8");
//String requestURI = req.getRequestURI();
MyHttpServletRequest myHttpServletRequest = new MyHttpServletRequest(req);
filterChain.doFilter(myHttpServletRequest, resp);
}
class MyHttpServletRequest extends HttpServletRequestWrapper{
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
//通过父类对象获取表单中的数据
String parameter = super.getParameter(name);
try {
parameter = new String(parameter.getBytes("iso-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return parameter;
}
}
}
这样子经过过滤器后的request.getParameter("username")
拿到的应该就不是乱码了
上一篇: latin1的mysql数据库如何本地打开而避免中文乱码
下一篇: http 请求报文