springboot-WebMvcConfigurer(拦截器、跨域访问、格式化、注册Controller)
WebMvcConfigurer是用来全局定制化Spring Boot的MVC特性。开发者通过实现WebMvcConfigurer接口来配置应用的MVC全局特性。
package com.gcz.conf.mvc; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.*; /** * @author guocz * @date 20210621 * MVC全局特性 */ public class MvcConfigurer implements WebMvcConfigurer { /** * 拦截器 * @param registry 注册 */ @Override public void addInterceptors(InterceptorRegistry registry){ } /** * 跨域访问配置 * @param registry 注册 */ @Override public void addCorsMappings(CorsRegistry registry){ } /** * 格式化 * @param registry 注册 */ @Override public void addFormatters(FormatterRegistry registry) { } /** * URI到视图的映射 * @param registry 注册 */ @Override public void addViewControllers(ViewControllerRegistry registry){ } // 其他更多全局定制接口 }
拦截器
通过addInterceptors方法可以设置多个拦截器,比如对特定的URI设定拦截器以检查用户是否登录,打印处理用户请求耗费的时间等。
例:
1、全局定制拦截器:
package com.gcz.conf.interceptor; import com.gcz.conf.interceptor.handler.SessionHandlerInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author guocz * @date 20210621 * 全局拦截器 */ @Configuration public class MvcInterceptor implements WebMvcConfigurer { /** * 拦截器 * @param registry 注册 */ @Override public void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(new SessionHandlerInterceptor()).addPathPatterns("/admin/**"); } }
2、会话处理类SessionHandlerInterceptor
package com.gcz.conf.interceptor.handler; import cn.hutool.core.util.StrUtil; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author guocz * @date 20210621 * 会话处理拦截器 */ public class SessionHandlerInterceptor implements HandlerInterceptor { private final static String TOKEN = "12345"; /** * Controller处理前 * @param request HttpServletRequest * @param response HttpServletResponse * @param handler 处理对象 * @return true or false * @throws Exception 异常 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Controller处理前"); String token =request.getParameter("token"); if (!StrUtil.equals(token, TOKEN)) { // 如果没登录,重定向到login.html response.getWriter().write("FAIL,PLEASE SIGN IN !"); response.setStatus(400); response.getWriter().close(); return false; } return true; } /** * Controller方法处理完毕后,调用此方法 * @param request HttpServletRequest * @param response HttpServletResponse * @param handler 处理对象 * @param modelAndView 视图 * @throws Exception 异常 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { System.out.println("Controller方法处理完毕后,调用此方法"); } /** * 页面渲染完毕后调用此方法,通常用来清除某些资源,类似Java语法的finally * @param request HttpServletRequest * @param response HttpServletResponse * @param handler 处理对象 * @param ex 异常 * @throws Exception 异常 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { System.out.println("页面渲染完毕后调用此方法,通常用来清除某些资源,类似Java语法的finally"); } }
3、相关调用测试
package com.gcz.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author guocz * @date 20210621 * 用户 */ @Controller @RequestMapping("/admin") public class UserController { @ResponseBody @RequestMapping("/getUser.json") public void getUser(HttpServletResponse response) throws IOException { response.getWriter().write("ON LINE"); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().close(); } @ResponseBody @RequestMapping("/checkUser.json") public void checkUser(HttpServletResponse response) throws IOException { response.getWriter().write("SUCCESS"); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().close(); } }
跨域访问
出于安全的考虑,浏览器会禁止AJAX访问不同域的地址。W3C的CORS规范(Cross-originresource sharing)允许实现跨域访问,并被现在大多数浏览器支持,包括:
Chrome 3+;
FireFox 3.5+;
Opera 12+;
Safari 4+;
Internet Explorer 8+;
1、拦截器
/** * 跨域访问 * @param registry 注册 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://domain2.com") .allowedMethods("POST", "GET"); }
格式化
将HTTP请求映射到Controller方法的参数上后,Spring会自动进行类型转化。对于日期类型的参数,Spring默认并没有配置如何将字符串转为日期类型。为了支持可按照指定格式转为日期类型,需要添加一个DateFormatter类:
1、拦截器
/** * 格式化 * @param registry 注册 */ @Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss")); }
2、入参
package com.gcz.entity.req; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Date; /** * @author guocz * @date 20210623 * 用户 */ @Data public class UserReq { /** * 日期 */ @NotNull(message = "日期不能为空") private Date date; }
3、调用类
package com.gcz.controller; import com.gcz.entity.req.UserReq; import org.springframework.stereotype.Controller; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; /** * @author guocz * @date 20210621 * 用户 */ @Controller @RequestMapping("/admin") public class UserController { @ResponseBody @RequestMapping("/checkFormatter.json") public void checkFormatter(@Validated UserReq req, HttpServletResponse response) throws IOException { Date date = req.getDate(); response.getWriter().write(date.toString()); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().close(); } }
4、调用格式:
注册Controller
应用有时候没必要为一个URL指定一个Controller方法,可以直接将URI请求转到对模板的渲染上。
例:
package com.gcz.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @author guocz * @date 20210630 * 入口 */ @Controller @RequestMapping("/") public class IndexController { public String index(){ return "/index.btl"; } }
可以直接通过ViewControllerRegistry注册一个
/** * 注册Controller * @param registry 注册 */ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("index.html").setViewName("/index.btl"); registry.addRedirectViewController("/**/*.do", "/index.html"); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)