过滤器:
Filter即为过滤器,用于在servlet之外对request和response进行修改。它主要用于对用户请求进行预处理,也可以对HttpAervletResponse进行后处理。使用Filter的完整流程,Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为Filter链。
过滤器链:执行顺序为,先配置的先执行,后配置的后执行
响应时顺序则相反。
请求用的多,响应配置的较少。
过滤器拦截例子
对过滤器进行配置(不是基于配置文件的,而是基于一个配置类的)
所拦截的请求路径为/s1
有三个生命周期方法。
@WebFilter("/s1")//如果此处为/*那么所有的请求都会进入到过滤器
public class FilterYZX implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//拦截请求,进行一些过滤
System.out.println("过滤器进行了拦截");
//对资源进行放行,使其进入Servlet。
filterChain.doFilter(servletRequest, servletResponse);
//这是必须的,必须对资源进行放行
}
@Override
public void destroy() {
System.out.println("过滤器进行了销毁");
}
}
@WebServlet("/s1")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入到servlet01");
}
}
当我们访问s1时
@WebServlet("/s2")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入到servlet02");
}
}
当我们访问s2时,并没有经过过滤器。
注意:tomcat7及以下版本,get和post请求都会出现乱码问题,都需要进行解决。
tomcat8以上,get请求不会出现乱码,只需要解决post的乱码问题。
post请求乱码问题:
1,request.setCharacterEncoding(“UTF-8”);这样就解决了。
2,配置文件解决
get请求乱码问题:
1,在代码中体现
String userName = New
String(Request.getParameter(“userName”).getBytes(“ISO8859-1”), “utf-8”);
将 ISO8859-1格式改为utf-8
2,在tomcat的配置文件中修改
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="utf-8" />
3,重写getParameter方法
拦截请求,分析版本,将请求改为utf-8格式。
package OnLine;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@WebFilter("/*")//拦截所有请求,因为所有的请求都有可能出现乱码问题
public class EcondingFilter implements Filter {
public EcondingFilter() {
}
public void destory() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//处理的乱码请求都是基于HTTP请求的
//所以我们需要将其转为HttpServletRequest,HttpServletResponse
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
//处理post请求乱码问题
httpServletRequest.setCharacterEncoding("utf-8");
//获取请求方法
String method = httpServletRequest.getMethod();
if (method.equalsIgnoreCase("get")) {
//获取服务器版本信息,如果低于7.0,那么重写get
String serverInfo = httpServletRequest.getServletContext().getServerInfo();
//得到具体的版本号
String version = serverInfo.substring(serverInfo.indexOf("/") + 1, serverInfo.indexOf("."));
if (Integer.parseInt(version) < 8) {
HttpServletRequest myRequest = new MyWapper(httpServletRequest);
//放行get请求
filterChain.doFilter(myRequest, httpServletResponse);
return;
}
}
//放行其他请求
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
class MyWapper extends HttpServletRequestWrapper {
HttpServletRequest request;
public MyWapper(HttpServletRequest request) {
super(request);
this.request=request;
}
@Override
public String getParameter(String name) {
String value=request.getParameter(name);
if (value!=null&&!(value.trim()).equals("")){
try {
value=new String(value.getBytes("ISO8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return value;
}
}
@Override
public void destroy() {
}
}
监听器
web监听器是Servlet中一种特殊的类,能够帮助开发者监听web种特定的事件,比如ServletContext,HttpSession,ServlerRequest的创建和销毁;变量的创建销毁和修改等
可以在某些动作前后进行增加处理,实现监听。例如统计在线人数。
监听器有三类八种
监听器都是接口,接口内的代码内容需要自己实现。
创建session监听器
@WebListener
public class MyListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("监听器监听到创建session");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("监听器监听到销毁session");
}
}
@WebServlet("/s1")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
}
}
@WebServlet("/s2")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().invalidate();
}
}
监听器小例子:
监听session的创建,当每有一个人开启一个session那么我们监听到了,就会将OnlineNumber+1;
package OnLine;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class OnLineListener implements HttpSessionListener {
private int OnlineNumber=0;
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("进来了");
OnlineNumber++;
se.getSession().setAttribute("OnlineNumber",OnlineNumber);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
se.getSession().invalidate();
OnlineNumber--;
se.getSession().setAttribute("OnlineNumber",OnlineNumber);
}
}
创建个假的servlet进行请求接收。
@WebServlet("/online")
public class OnLineServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应格式,以及编码规则
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("当前在线人数为"+req.getSession().getAttribute("OnlineNumber"));
}
}
bug1:我们不能让tomcat直接进行启动浏览器,否则我们发完请求人数直接为2
设置:
然后我们自己打开浏览器,自己授敲路径。
bug2:当我们随着session的增加,但是最开始打开的网页的在线人数是不变的??
为什么?
因为session在当前浏览器存活,只要你不关闭,你的数据一直不会变。
解决办法?
扩大存储范围》》》存到整个应用中applicationContext里。
package OnLine;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/online")
public class OnLineServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String key = req.getParameter("key");
System.out.println(key);
if(key!=null&&key.equals("yzx")){
req.getSession().invalidate();
return;
}
//设置响应格式,以及编码规则
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("当前在线人数为"+req.getSession().getServletContext().getAttribute("OnlineNumber")+"<a href='online?key=yzx'>退出</a>");
}
}
该监听器将OnlineNumber放在了整个应用的域上
package OnLine;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class OnLineListener implements HttpSessionListener {
private int OnlineNumber = 0;
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("进来了");
OnlineNumber++;
se.getSession().getServletContext().setAttribute("OnlineNumber", OnlineNumber);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
se.getSession().invalidate();
OnlineNumber--;
se.getSession().getServletContext().setAttribute("OnlineNumber", OnlineNumber);
}
}