应用场景
项目中要拦截指定url之外的所有请求,并在请求进入controller之前判断其中的参数是否合法正确.
- 注册拦截器:继承 WebMvcConfigurationSupport ,重写 addInterceptors 方法
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private JumpControllerInterceptor jumpControllerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
# 这里添加的路径不包含项目的contextPath哦 registry.addInterceptor(jumpControllerInterceptor).addPathPatterns("/**").
excludePathPatterns("/test");
super.addInterceptors(registry);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String os = System.getProperty("os.name");
//如果是Windows系统
// if (os.toLowerCase().startsWith("win")) {
// registry.addResourceHandler("/app_file/**")
// // /app_file/**表示在磁盘filePathWindow目录下的所有资源会被解析为以下的路径
// .addResourceLocations("file:" + filePathWindow);
// } else { //linux 和mac
// registry.addResourceHandler("/app_file/**")
// .addResourceLocations("file:" + filePathLinux) ;
// }
registry.addResourceHandler("/jumpLogs/**").addResourceLocations("file:jumpLogs/");
super.addResourceHandlers(registry);
}
}
实现HandlerInterceptor这个接口
@Component public class JumpControllerInterceptor implements HandlerInterceptor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object o) { String requestURI = req.getRequestURI(); if(requestURI.startsWith("/jump/app/")){ logger.info("正在检查pathVariable: appCode"); Map pathVariables = (Map) req.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); String appCode = (String)pathVariables.get("appCode"); /* 2.判断是否IDP登录 */ AppAddrMapping appAddrMapping = AppAddrMapping.ADDR_MAPPING_MAP.get(appCode); if (null == appAddrMapping) { logger.error("当前url中的appCode : {} 和app.json中的不相匹配,请检查配置文件",appCode); throw new ConfArgException("app不存在,请检查appcode是否正确"); } } return true; } @Override public void postHandle(HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView mav) { } @Override public void afterCompletion(HttpServletRequest req, HttpServletResponse rep, Object o, Exception e) { }
- 拦截器不起作用的原因
a)
继承 WebMvcConfigurationSupport ,重写 addInterceptors 方法的类需用到@Configuration 注解b)
addPathPatterns中的问题。拦截器最后路径一定要 /, 如果是目录的话则是 /*/c)
excludePathPatterns 或 addPathPatterns 书写错误,前面添加了项目的ContextPath 拦截器的主要方法
configurePathMatch:配置路由请求规则 configureContentNegotiation:内容协商配置 configureAsyncSupport configureDefaultServletHandling:默认静态资源处理器 addFormatters:注册自定义转化器 addInterceptors:拦截器配置 addResourceHandlers:资源处理 addCorsMappings:CORS配置 addViewControllers:视图跳转控制器 configureViewResolvers:配置视图解析 addArgumentResolvers:添加自定义方法参数处理器 addReturnValueHandlers:添加自定义返回结果处理器 configureMessageConverters:配置消息转换器。重载会覆盖默认注册的HttpMessageConverter extendMessageConverters:配置消息转换器。仅添加一个自定义的HttpMessageConverter. configureHandlerExceptionResolvers:配置异常转换器 extendHandlerExceptionResolvers:添加异常转化器 getValidator getMessageCodesResolver
- 其中用的比较多的是一下三个接口:
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
/** 添加拦截器 **/
void addInterceptors(InterceptorRegistry registry);
/** 静态资源处理 **/
void addResourceHandlers(ResourceHandlerRegistry registry);
@Configuration
public class AddCorsMappings extends WebMvcConfigurationSupport {
/**
* 跨域访问配置接口
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowCredentials(true)
.allowedHeaders("*")
.maxAge(3600);
}
}
非常重要的提示:Springboot中只能有一个WebMvcConfigurationSupport配置类是真正起作用的,对于这个问题,其实可以通过implements WebMvcConfigurer来解决,多个不同的类实现这个接口后的配置都可以正常运行。
关于用Servlet获取URL地址。
在HttpServletRequest类里,有以下六个取URL的函数
getContextPath
取得项目名 getServletPath
取得Servlet名 getPathInfo
取得Servlet后的URL名,不包括URL参数 getRequestURL
取得不包括参数的URL getRequestURI
取得不包括参数的URI,即去掉协议和服务器名的URL
具体如下图:
相对应的函数的值如下:
getContextPath:/ServletTest
getServletPath:/main
getPathInfo:/index/testpage/test
getRequestURL:http://localhost:8080/Servlet...
getRequestURI:/ServletTest/main/index/testpage/test
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。