执行顺序:
Javaweb
context-param-->listener-->filter-->servlet
Springmvc
context-param-->listener-->filter-->servlet-->interceptor(指的是拦截器),为什么拦截器是在servlet执行之后,因为拦截器本身就是在servlet内部的
使用技巧:
需要监听到项目中的一些信息,并且不需要对流程做更改时,用监听器;当需要过滤掉其中的部分信息,只留一部分时,就用过滤器;当需要对其流程进行更改,做相关的记录时用拦截器。过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应
(ps:类似aop)
过滤器
public class urlEncodeFilter implements Filter{
Logger logger = LoggerFactory.getLogger(urlEncodeFilter.class);
Map<String,Object> paramMap = new HashMap<String,Object>();
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
System.out.println("urlEncodeFilter doFilter..."+paramMap.get("urlEncode").toString());
arg0.setCharacterEncoding(paramMap.get("urlEncode").toString());
arg2.doFilter(arg0, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
String urlEncode = arg0.getInitParameter("urlEncode");
paramMap.put("urlEncode",urlEncode);
}
}
<filter>
<filter-name>urlEncodeFilter</filter-name>
<filter-class>com.mycompany.mvc.filter.urlEncodeFilter</filter-class>
<init-param>
<param-name>urlEncode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>urlEncodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
拦截器:
<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<bean class="com.host.app.web.interceptor.AllInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/test/number.do"/>
<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
<bean class="com.host.app.web.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
public class LogsInterceptor extends HandlerInterceptorAdapter {
private static final Logger logger = LoggerFactory.getLogger(LogsInterceptor.class);
private NamedThreadLocal<String> logContext = new NamedThreadLocal<String>("log-id");
@Autowired
private TLogDao logDao;
/**
* preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用,
* SpringMVC中的Interceptor拦截器是链式的,可以同时存在多个Interceptor,
* 然后SpringMVC会根据声明的前后顺序一个接一个的执行,
* 而且所有的Interceptor中的preHandle方法都会在Controller方法调用之前调用。
* SpringMVC的这种Interceptor链式结构也是可以进行中断的,
* 这种中断方式是令preHandle的返回值为false,当preHandle的返回值为false的时候整个请求就结束了。
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String host = request.getRemoteHost();
String url = request.getRequestURI();
TLogEntity entity = new TLogEntity();
entity.setCreateTime(new Timestamp(System.currentTimeMillis()));
entity.setCreateUser("admin");
entity.setIpAddress(host);
entity.setLogUrl(url);
entity.setIsSuccess("N");
logDao.save(entity);
logContext.set(entity.getLogId());
logger.debug("IP为---->>> " + host + " <<<-----访问了系统");
return true;
}
/**
* 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。
* postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 后, 也就是在Controller的方法调用之后执行,
* 但是它会在DispatcherServlet进行视图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操作。
* 这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用,
* 这跟Struts2里面的拦截器的执行过程有点像,
* 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,
* Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor或者是调用action,
* 然后要在Interceptor之前调用的内容都写在调用invoke之前,要在Interceptor之后调用的内容都写在调用invoke方法之后。
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。
* 该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, 这个方法的主要作用是用于清理资源的,
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
String host = request.getRemoteHost();
String logId = logContext.get();
TLogEntity entity = logDao.findOne(logId);
entity.setIsSuccess("Y");
logDao.save(entity);
logger.debug("IP为---->>> " + host + " <<<-----访问成功");
}
}
监听器:
按监听的对象划分,可以分为
ServletContext对象监听器
HttpSession对象监听器
ServletRequest对象监听器
按监听的事件划分
对象自身的创建和销毁的监听器
对象中属性的创建和消除的监听器
session中的某个对象的状态变化的监听器
<listener> <listener-class>
com.mycompany.mvc.listener.myServletContextListener
</listener-class>
</listener>
<listener>
<listener-class>
com.mycompany.mvc.listener.myServletContextAttributeListener
</listener-class>
</listener>
public class myHttpSessionListener implements HttpSessionListener{
public static int peopleOnLine = 0;
@Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("myHttpSessionListener.sessionCreated():"+arg0);
peopleOnLine++;
arg0.getSession().setAttribute("peopleOnLine",peopleOnLine);
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("myHttpSessionListener.sessionDestroyed():"+arg0);
peopleOnLine--;
arg0.getSession().setAttribute("peopleOnLine",peopleOnLine);
}
}
拦截器实例:
public class AdminLoginHandlerInterceptor extends LoginHandlerInterceptor {
@Autowired
private BaseService baseService;
@Override
@SuppressWarnings("unchecked")
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if(request.getServletPath().matches(".*/((assets)|(js)|(images)|(common)|(public)).*") || request.getServletPath().contains("/api")){
super.postHandle(request, response, handler, modelAndView);
return;
}
Object hd = request.getSession().getAttribute(Constant.SESSION_MENU);
if(modelAndView != null && hd != null) {
Map<String,String> subsetMap = this.checkSubset();
modelAndView.addObject("hd", hd);
Map<String, Boolean> authMap = new HashMap<String, Boolean>();
Map<String, Object> headerInfo = (Map<String, Object>)hd;
Object obj = headerInfo.get("menuList");
if(obj != null) {
for(Menu menu : (List<Menu>)obj) {
menu.setActive(false);
if(request.getServletPath().endsWith(menu.getUrl()) || (subsetMap.containsKey(menu.getUrl()) && subsetMap.get(menu.getUrl()).contains(request.getServletPath()))) {
addAuthButton(authMap, menu);
menu.setActive(true);
break;
}
boolean isEnd = false;
if(menu.getSubMenu() != null && menu.getSubMenu().size() > 0) {
for(Menu subMenu : menu.getSubMenu()) {
if(StringUtils.isBlank(subMenu.getUrl())) {
continue;
}
if(request.getServletPath().endsWith(subMenu.getUrl())) {
addAuthButton(authMap, subMenu);
menu.setActive(true);
isEnd = true;
break;
}
}
}
if(isEnd) {
break;
}
}
}
modelAndView.addObject("auth", authMap);
List<SysSystemConfig> configList = baseService.getList(
SysSystemConfig.class,
Collections.singletonList(Where.in(SysSystemConfigDomain.NID, new String[]{"site_logo", "site_name", "site_keywords", "site_discription", "site_copyright"})),
Parameter.queryColumn(new String[] {SysSystemConfigDomain.NID,SysSystemConfigDomain.VALUE})
);
if(configList != null && configList.size() > 0) {
for(SysSystemConfig config : configList) {
if("site_logo".equals(config.getNid())) {
modelAndView.addObject(config.getNid(), PropertiesUtil.getImageHost() + config.getValue());
} else {
modelAndView.addObject(config.getNid(), config.getValue());
}
}
}
}
super.postHandle(request, response, handler, modelAndView);
}
private void addAuthButton(Map<String, Boolean> authMap, Menu menu) {
if(menu == null || menu.getSubMenu() == null) {
return;
}
for(Menu btn : menu.getSubMenu()) {
if(!btn.getUrl().startsWith("btn:") || !btn.isChecked() ) {
continue;
}
authMap.put(btn.getUrl().replace("btn:", ""), true);
}
}
private Map<String, String> checkSubset() {
Map<String, String> subsetMap = new HashMap<String, String>();
subsetMap.put("platform/manager/list", "/platform/manager/detail,");
subsetMap.put("project/loan/list", "/project/loan/detail,");
subsetMap.put("loan/loan/list", "/loan/loan/detail,");
return subsetMap;
}
}
public class LoginHandlerInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String path = request.getServletPath();
if ("/".equals(path))
return true;
if (path.matches(".*/((assets)|(js)|(images)|(common)|(public)).*"))
return true;
for (String newPath : list) {
if (path.matches(newPath)) {
return true;
}
}
if (request.getSession().getAttribute(Constant.SESSION_USER) == null) {
System.out.println("---------------");
response.sendRedirect(request.getContextPath() + Constant.LOGIN_URL);
return false;
}
return true;
}
/**
* 免拦截的url
*/
public static List<String> list = new ArrayList<String>();
static {
//备案平台管理
list.add("/platform/list");
list.add("/platform/toList");
list.add("/platform/listpage");
list.add("/platform/detail");
list.add("/platform/detailpage");
list.add("/system/platform/checkNum");
list.add("/system/platform/info");
list.add("/system/platform/toIndex");
list.add("/platform/listDetail");
list.add("/platform/statistics/risk");
//用户中心
list.add("/member/member/memberInfo");
list.add("/api/project") ;
list.add("/api/repay") ;
list.add("/phone/location/get") ;
}
}