2019独角兽企业重金招聘Python工程师标准>>>

首先来看一下@RequestMapping这个注解

public @interface RequestMapping {/**方法要拦截的url集合*/String[] value() default {};/**url访问的方法集合*/RequestMethod[] method() default {};}

看一下下面的例子

@RequestMapping(value = {"/listRole", "/listRole2"}, method = {RequestMethod.GET, RequestMethod.POST})
public List<Role> listRole() {return ...;
}

上面的例子表示以下的访问链接都将访问listRole()这个方法,需要注意的是:如果没有配置method,那么所有访问的Request Method类型都将满足。

Request URL Request Method
/listRole GET
/listRole POST
/listRole2 GET
/listRole2 POST

springmvc中将@RequestMapping解析为org.springframework.web.servlet.mvc.method.RequestMappingInfo,对应的方法信息存在org.springframework.web.method.HandlerMethod中,通过org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping可以获取到所有RequestMappingInfo以及对应的HandlerMethod。

通过下面的代码来分析

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.eduboss.annotations.AliyunLogFilterIgnore;
import com.eduboss.domain.User;
import com.eduboss.dto.DataPackage;
import com.eduboss.dto.DataPackageForJqGrid;
import com.eduboss.logger.LoggerHelper;
import com.eduboss.logger.WapperedResponse;
import com.eduboss.service.UserService;
import com.eduboss.utils.AliyunSLSUtils;
import com.eduboss.utils.PropertiesUtils;
import com.eduboss.utils.StringUtil;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;public class AliyunLogFilter implements Filter {private static final Logger log = LoggerFactory.getLogger(AliyunLogFilter.class);private Map<String, Map<String, RequestToMethodItem>> urlControllerMappings = new HashMap<>(1024);private ThreadLocal<Long> startTimeHolder = new ThreadLocal<>();private ThreadLocal<Long> endTimeHolder = new ThreadLocal<>();private static final String ALL_METHOD_TYPE = "[]";//系统中访问的url后缀,一般controller没有配置,需要去除private static final String[] suffixs = new String[]{".do"};@Overridepublic void init(FilterConfig filterConfig) throws ServletException {loadUrlControllerMappings(filterConfig);}//加载url对应的controller信息private void loadUrlControllerMappings(FilterConfig filterConfig) {String contextPath = filterConfig.getServletContext().getContextPath();WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();//获取所有的RequestMappingMap<String, HandlerMapping> allRequestHandlerMappings = BeanFactoryUtils.beansOfTypeIncludingAncestors(webApplicationContext, HandlerMapping.class, true, false);for (HandlerMapping handlerMapping : allRequestHandlerMappings.values()) {//这里只需要RequestMappingHandlerMapping中的URL映射if (handlerMapping instanceof RequestMappingHandlerMapping) {RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) handlerMapping;Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();for (Map.Entry<RequestMappingInfo, HandlerMethod> requestMappingInfoHandlerMethodEntry : handlerMethods.entrySet()) {RequestMappingInfo requestMappingInfo = requestMappingInfoHandlerMethodEntry.getKey();HandlerMethod mappingInfoValue = requestMappingInfoHandlerMethodEntry.getValue();RequestMethodsRequestCondition methodCondition = requestMappingInfo.getMethodsCondition();//url可以访问的method类型Set<RequestMethod> methods = methodCondition.getMethods();Set<String> requestMethodNames = new HashSet<>();methods.forEach(e -> requestMethodNames.add(e.name().toUpperCase()));PatternsRequestCondition patternsCondition = requestMappingInfo.getPatternsCondition();//可以访问的urlSet<String> urlPatterns = patternsCondition.getPatterns();Class<?> controllerClass = mappingInfoValue.getBeanType();Method controllerMethod = mappingInfoValue.getMethod();Class<?>[] methodParamTypes = mappingInfoValue.getMethod().getParameterTypes();Class<?> requestType = mappingInfoValue.getMethod().getReturnType();for (String url : urlPatterns) {url = contextPath + url;Map<String, RequestToMethodItem> mappings = urlControllerMappings.get(url);if (mappings == null) {mappings = new HashMap<>();urlControllerMappings.put(url, mappings);}if (requestMethodNames.isEmpty()) {//如果为空,说明所有method类型都可以访问mappings.put(ALL_METHOD_TYPE, new RequestToMethodItem(url, ALL_METHOD_TYPE, controllerClass, controllerMethod, methodParamTypes, requestType));} else {for (String mName : requestMethodNames) {mappings.put(mName, new RequestToMethodItem(url, mName, controllerClass, controllerMethod, methodParamTypes, requestType));}}}}}}}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;startTimeHolder.set(System.currentTimeMillis());chain.doFilter(httpServletRequest, httpServletResponse);endTimeHolder.set(System.currentTimeMillis());addLog(httpServletRequest, httpServletResponse);}private void addLog(HttpServletRequest request, HttpServletResponse response) {Map<String, String> contents = Maps.newLinkedHashMap();setRequestInfo(request, contents);setControllerInfo(request, response, contents);setResponseInfo(response, contents);log.info(contents.toString());//可以根据自己的需要进行记录}private void setResponseInfo(HttpServletResponse response, Map<String, String> contents) {contents.put("startTime", startTimeHolder.get().toString());contents.put("endTime", endTimeHolder.get().toString());contents.put("consumedTime", (endTimeHolder.get() - startTimeHolder.get()) + "");contents.put("status", response.getStatus() + "");}//这里是设置用户的访问信息private void setRequestInfo(HttpServletRequest request, Map<String, String> contents) {String uri = request.getRequestURI();String method = request.getMethod().toUpperCase();String remoteHost = request.getRemoteHost();String sessionId = request.getSession().getId();StringBuilder params = new StringBuilder();Enumeration<String> keys = request.getParameterNames();while (keys.hasMoreElements()) {String k = keys.nextElement();String[] v = request.getParameterValues(k);if (params.length() == 0) {params.append("{");} else {params.append(",");}params.append(k).append("=");if (v.length == 1) {params.append(v[0]);} else {params.append(Arrays.toString(v));}}if (params.length() > 0) {params.append("}");} else {params.append("{}");}contents.put("requestUri", uri);contents.put("requestMethod", method);contents.put("remoteHost", remoteHost);contents.put("sessionId", sessionId);contents.put("params", params.toString());}private void setControllerInfo(HttpServletRequest request, HttpServletResponse response, Map<String, String> contents) {String uri = request.getRequestURI();String method = request.getMethod().toUpperCase();//去掉后缀uri = removeSuffix(uri);String path = getAntPathMatchUrl(uri, urlControllerMappings.keySet());Map<String, RequestToMethodItem> requestToMethodItems = urlControllerMappings.get(path);RequestToMethodItem item = null;if (requestToMethodItems != null) {item = requestToMethodItems.get(ALL_METHOD_TYPE);if (item == null) {item = requestToMethodItems.get(method);}}if (item != null) {contents.put("controllerClassName", item.controllerClassName);contents.put("controllerMethodName", item.controllerMethodName);contents.put("controllerMethodParameterTypeNames", item.methodParmaTypesName);contents.put("controllerMethodReturnTypeName", item.returnTypeName);}}private String getAntPathMatchUrl(String uri, Set<String> patternUrls) {if (patternUrls.contains(uri)) {return uri;}String path = null;//通配判断AntPathMatcher matcher = new AntPathMatcher();for (String pt : patternUrls) {if (matcher.match(pt, uri)) {path = pt;break;}}return path;}private String removeSuffix(String uri) {for (String sf : suffixs) {if (uri.endsWith(sf)) {uri = uri.substring(0, uri.length() - sf.length());break;}}return uri;}@Overridepublic void destroy() {}private class RequestToMethodItem {String requestUrl;String requestMethod;Class<?> controllerClass;Method controllerMethod;Class<?>[] methodParmaTypes;Class<?> returnType;String controllerClassName;String controllerMethodName;String methodParmaTypesName;String returnTypeName;public RequestToMethodItem(String requestUrl, String requestMethods, Class<?> controllerClass, Method controllerMethod, Class<?>[] methodParmaTypes, Class<?> returnType) {this.requestUrl = requestUrl;this.requestMethod = requestMethods;this.controllerClass = controllerClass;this.controllerMethod = controllerMethod;this.methodParmaTypes = methodParmaTypes;this.returnType = returnType;this.controllerClassName = controllerClass.getName();this.controllerMethodName = controllerMethod.getName();if (returnType != null) {returnTypeName = returnType.getName();} else {returnTypeName = Void.class.getName();}methodParmaTypesName = Arrays.toString(methodParmaTypes);}@Overridepublic String toString() {return "requestUrl: " + requestUrl + ", requestMethod: " + requestMethod + ", controllerClassName: " + controllerClassName + ", controllerMethodName: " + controllerMethodName+ ", methodParmaTypes: " + methodParmaTypesName + ", returnType: " + returnTypeName;}}}

转载于:https://my.oschina.net/linchuhao23/blog/2247131

springmvc获取url对应的controller,并拦截记录每次访问的controller方法相关推荐

  1. springmvc学习笔记二:重定向,拦截器,参数绑定

    springmvc学习笔记二:重定向,拦截器,参数绑定 Controller方法返回值 返回ModelAndView controller方法中定义ModelAndView对象并返回,对象中可添加mo ...

  2. js 获取url问号前_js获取历史url

    js获取历史url以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一.JS高手呢,获取历史网址 你的问题涉及到 Same ...

  3. springMVC3.0(文件上传,@RequestMapping加参数,@SessionAttributes,@ModelAttribute,转发,重定向,数值获取,传参,ajax,拦截器)

    1.项目包结构如下: 2.       spring配置文件springMVC.xml修改如下: <?xml version="1.0" encoding="UTF ...

  4. springMVC获取异步请求的参数,返回异步请求数据(json),跨域访问简单了解,文件上传,与Restful风格

    springMVC获取异步请求的参数 JQuery发送异步请求回顾 <a href="javascript:void(0);" id="testAjax" ...

  5. SpringMVC获取参数的几种方式

    SpringMVC获取参数的几种方式 前言: 年末了,忙了一年了却发现系统的整理的东西很少,一些基础的东西都未做整理,这里就将它随便整理一下,增加一些印象,当然在网上看到一些好的资料也会整理下来以备后 ...

  6. SpringMvc的Url映射和传参案例(转)

    Springmvc的基本使用,包括url映射.参数映射.页面跳转.ajax和文件上传 以前学习的时候写的代码案例,今天整理笔记的时候找到了,很久没有来园子了,发上来当个在线笔记用吧,免的时间长了又忘了 ...

  7. SpringMVC获取前端传来的json数据的四种方法(前后端json交互总结)

    一.导包 一定要有 Jackson 的jar包依赖,就算有了fastjson,也要有Jackson包 <dependency><groupId>com.fasterxml.ja ...

  8. springboot获取多个请求参数_springboot获取URL请求参数的多种方式

    1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交. /** * 1.直接把表单的参数写在Controller相应的方法的形参中 * @pa ...

  9. SpringMVC获取response的问题

    SpringMVC获取response的问题: 关于用以下这种方式获取response的一些问题: ((ServletWebRequest) RequestContextHolder.getReque ...

  10. javeWeb springMvc获取到的参数附带特殊符号,接收后被转义

    javeWeb springMvc获取到的参数附带特殊符号,接收后被转义 https://blog.csdn.net/yejingxuan01/article/details/78802340 版权声 ...

最新文章

  1. tcp断开连接,4次握手,为什么wireshark 只能抓到3个包?
  2. R语言可视化包ggplot2绘制分组的条形图(bar plot、柱状图)实战:多变量柱状图
  3. Java提取mssql备份文件的数据
  4. 设计模式笔记——Bridge
  5. ios10前台收到推送_iOS 13 beta 2 推送 | iOS 13 热门疑问解答
  6. Essential Studio for Windows Forms发布2017 v2,持office 2016和主题定制
  7. golang中的variable和data types
  8. @echo off是什么意思_高街、BF、FOG、OS风。。。都是些什么鬼?
  9. JavaAPI之Runtime类以及bat文件开启应用程序
  10. (转)用Javascript获取页面元素的位置
  11. 为人处世:处世22条忠告
  12. iWebOffice使用VBA控制字体
  13. 可能是最全的Kotlin协程讲解
  14. 云优CMS企业网站管理系统 v2.2.2 分站版
  15. 百度搜索无法显示搜索结果
  16. 收集:Programer Jokes
  17. vscdoe常用快捷键
  18. Wireshark、Sniffer 两款网络分析工具的比较
  19. 关于QtCreator中三种不同编译版本 debug、release、profile 的区别
  20. 智能车|直流电机、编码器与驱动器---减速器

热门文章

  1. Windows下PyMC安装
  2. Android 利用SurfaceView进行图形绘制
  3. (并查集) Wireless Network --POJ --2236
  4. iOS 百度地图SDK接入与使用指南(以导航SDK为例):下载SDK、运行报错修改、代码编辑等
  5. JAVA-JVM调优标志
  6. LeetCode 148 排序链表
  7. 低危漏洞- X-Frame-Options Header未配置
  8. String类的两种赋值
  9. Sql 行转换列(列转换行), JavaScript解决思路
  10. 不要奢望.NET能够跨平台