黑马程序员技术交流社区
标题:
【广州校区】+【原创】listener
[打印本页]
作者:
Mylo
时间:
2019-2-21 15:03
标题:
【广州校区】+【原创】listener
filter
filter会比listener用的多得多
Spring想要接入到项目中需要用到Listener
Strut想要接入到项目中需要用到Filter
过滤器Filter(筛请求的)
在真正访问资源之前有一层过滤
filter的简介
filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理
快速入门
编写一个过滤器的类实现Filter接口
实现接口中尚未实现的方法(着重实现doFilter方法)
在web.xml中进行配置(主要是配置要对哪些资源进行过滤)(配置方法跟servlet一样)
filter拦截之后需要放行才能访问到相应的资源地址,不然就执行完dofilter方法后停止
public class QuickFilter implements Filter {
public void destroy() {
System.out.println("QuickFilter1销毁");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("QuickFilter1 doFilter调用");
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("QuickFilter1初始化");
}
}<!--web.xml-->
<filter>
<filter-name>QuickFilter</filter-name>
<filter-class>com.itcast.filter.QuickFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>QuickFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
filter的访问流程
客户端发送请求给服务器时,tomcat请求会先获取到请求信息,创建对应点request和response对象
如果不添加过滤的话,tomcat引擎会带着request和response对象创建servlet,并把参数传递过去
如果添加了filter,则会在servlet之间设置了过滤器
在过滤器中需要调用chain.doFilter(request,response)后,请求才能被放行去找资源文件
filter作用
对request和response进行配置值
权限过滤
filter的API
filter生命周期及其与生命周期相关的方法
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
init(Filterconfig):代表filter对象初始化方法,filter对象创建时执行(==服务器一启动就创建filter对象==)
doFilter(ServletRequest,ServletResponse,FilterChain):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法
FilterChain内部维护着各个filter的索引
destory():代表是filter销毁方法,当filter对象销毁时执行该方法
==Filter对象的生命周期==
Filter何时创建:服务器启动时就创建该filter对象
Filter何时销毁:服务器关闭时filter销毁
Filter的AP详解
init(FilterConfig):其中参数config代表该Filter对象的配置信息的对象,内部封装是该filter的配置信息
destory()方法:filter对象销毁时执行
doFilter方法:doFilter(ServletRequest,ServletResponse,FilterChain)
其中的参数:
ServletRequest/ServletResponse:每次在执行doFilter方法时web容器负责创建一个request和一个response对象作为doFilter的参数传递进来
该request和response就是在访问目标资源的service方法时的request和response(其实不是同一个对象,但是里面的数据是一样的)
FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
Filter的配置
url-pattern配置时
完全匹配 /sertvle1
目录匹配 /aaa/bbb/* ----用的最多
/user/*:访问前台的资源进入此过滤器
/admin/*:访问后台的资源时执行此过滤器
扩展名匹配 *.abc *.jsp(扩展名匹配只能以*开头)
注意:url-pattern可以使用servlet-name替代,也可以混用(开发中url-pattern用的多)
dispatcher:访问的方式(了解,基本不用,面试也不问)
REQUEST:默认值,代表直接访问某个资源时执行filter
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转是执行filter
总结Filter的作用?
自动登录
公共代码的提取(解决乱码问题)
屏蔽非法文字
进行响应数据的压缩
可以对request和response中的方法进行增强(装饰者模式/动态代理)
进行权限控制
登陆的基本实现
登陆成功会进行重定向跳转,在跳转之前,把用户对象存到session中(所有公司都这么干)
在主页显示用户名,如果用户登陆了话
<!--用于提示用户名和密码错误-->
<div>
<span style="color: red">${info }</span>
</div>//web层
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
UserService service = new UserService();
User user = service.login(username,password);
if (user == null) {
//登陆失败
request.setAttribute("info", "用户名或密码错误");
request.setAttribute("username", username);//把用户名带回去页面
request.getRequestDispatcher("/login.jsp").forward(request, response);
}else {
//登陆成功,把用户对象存放在session中
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/index.jsp");
}
}<!--index.jsp-->
<c:if test="${sessionScope.user == null }"> <!--${empty user }-->
<li><a href="login.jsp">登录</a></li>
<li><a href="register.jsp">注册</a></li>
</c:if>
<c:if test="${sessionScope.user != null }"> <!--${not empty user }-->
<li>欢迎:${sessionScope.user.realname }</li>
<li><a href="javascript:void(0)">退出</a></li>
</c:if>
自动登录
后期开发会接触到token来记住登陆
把用户信息存放到cookie,访问的时候带过去自动帮你登陆.但是这样做的话,每个servlet都要加上自动登录的逻辑
在filter中一般都会对request进行强转-->HttpServletRequest
//登陆成功后
String autoLogin = request.getParameter("autoLogin");//null or "autoLogin"
if(autoLogin != null && autoLogin.equals("autoLogin")) {
Cookie cookie_username = new Cookie("username", username);
Cookie cookie_pwd = new Cookie("password", password);
cookie_username.setMaxAge(60 * 24 * 3);
cookie_pwd.setMaxAge(60 * 24 * 3);
response.addCookie(cookie_username);
response.addCookie(cookie_pwd);
}//filter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
User user = (User) req.getSession().getAttribute("user");
if(user != null) {
chain.doFilter(request, response);
return;
}
String usrename = null;
String password = null;
Cookie[] cookies = req.getCookies();
if (cookies == null) {
chain.doFilter(request, response);
return;
}
for (Cookie co : cookies) {
if ("username".equals(co.getName())) {
usrename = co.getValue();
}
if ("password".equals(co.getName())) {
password = co.getValue();
}
}
if(usrename != null && password != null) {
UserService service = new UserService();
user = service.login(usrename, password);
}
if(user == null) {
chain.doFilter(request, response);
return;
}else {
req.getSession().setAttribute("user", user);
chain.doFilter(req, response);
}
}
解决全局乱码问题
cookie不能写中文,怎么结局cookie写中文的问题
先把中文编码,然后再解码
URLEncoder.encode(String s,String encodeType)
URLDeocder.decode(String s,String encodeType)
filter中对请求体的数据进行编码
request.setCharacterSet("UTF-8")
response.setContextType("text/html;charset=utf-8");
对于get请求的参数:
在filter中对request进行增强(装饰设计模式)
javaEE工程师提供了HttpServletRequestWrapper(专门用于装饰者提供的)
重写getParameter(),getParameterMap()..
class EncoderRequest extends HttpServletRequestWrapper {
private HttpServletRequest request = null;
private boolean isGet = false;
public EncoderRequest(HttpServletRequest request) {
super(request);
this.request = request;
isGet = "get".equals(request.getMethod().toLowerCase())? true:false;
}
@Override
public String getParameter(String name) {
String parameter = request.getParameter(name);
if (isGet) {
try {
parameter = new String(parameter.getBytes("iso8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return parameter;
}
}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
req.setCharacterEncoding("utf-8");
res.setContentType("utf-8");
EncoderRequest enRequest = new EncoderRequest(req);
chain.doFilter(enRequest, response);
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2