SpringMVC原理操作流程,拦截器,过滤器,参数,跨域
Posted 宇宙磅礴而冷漠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC原理操作流程,拦截器,过滤器,参数,跨域相关的知识,希望对你有一定的参考价值。
执行流程
springmvc流程图:
执行流程:
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
4、DispatcherServlet调用HandlerAdapter处理器适配器
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
拦截器
原理图:
拦截代码示例:
配置拦截器规则
//import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class UserIntercepter implements HandlerInterceptor {
@Autowired
private JedisCluster jedisCluster;
@Override
//handler是处理器,这个方法是处理器执行之前
//false表示拦截,true放行
//一般配合重定向,没有认证跳登陆页面
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String ticket=CookieUtil.getCookieValue(request,"TICKET" );
if(StringUtils.hasLength(ticket)){
if(jedisCluster.exists(ticket)){
//从redis把数据获取
String json=jedisCluster.get(ticket);
User user=ObjectMapperUtil.toObject(json, User.class);
//1.利用request把userId给controller
request.setAttribute("USER", user);
//2.第二种写法
UserThreadLocal.set(user);
return true;
}
}
response.sendRedirect("/user/login.html");
//request.getRequestDispatcher("/user/login.html").forward(request,response);
return false;
}
//处理器执行之后
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
//业务调用结束前,渲染之后
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//清空request对象
//清空threadLocal对象
request.removeAttribute("USER");
UserThreadLocal.remove();
}
}
装载拦截器
@Configuration
public class MvcConfigurer implements WebMvcConfigurer{
@Autowired
private UserIntercepter userIntercepter;
//开启匹配后缀型配置
//@Override
//public void configurePathMatch(PathMatchConfigurer configurer) {
// configurer.setUseSuffixPatternMatch(true);
//}
//装载关键代码,完成拦截器配置,路径开头斜杠很重要,不然可能会造成阻塞
@Override
public void addInterceptors(InterceptorRegistry registry) {
// *当前子,**子和子路径
registry.addInterceptor(userIntercepter)
.addPathPatterns("/cart/**","/order/**");
}
}
过滤器
//HttpFilter实现了Filter
@Configuration
public class MyHttpFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpSession session=request.getSession();
System.out.println(session.getAttribute("name"));
session.setAttribute("name", "哈哈哈哈");
System.out.println("过滤器,客户端向Servlet发送的请求被我拦截到了");
super.doFilter(request, response, chain);//源码执行chain.doFilter(request, response);
System.out.println("过滤器,Servlet向客户端发送的响应被我拦截到了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("http初始化");
super.init(filterConfig);
}
@Override
public void destroy() {
System.out.println("http销毁");
}
}
拦截器与过滤器执行顺序图解
流程顺序图:
接收参数&返回类型
接收参数
常用普通风格类型直接接收:
public String doPath(String name)
restFul风格:@RequestMapping("/doPath/{oid}/{name}"):
public String doPath(@PathVariable("oid") Integer id,@PathVariable String name)
pojo对象接收:
public String doPath(User user)
普通风格map:
public String doPath(@RequestParam Map<String,Object> map)
restFul风格map:
public String doPath(@PathVariable Map<String,Object> map)
日期类型:
public String doPath(String name,@DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam(required = true) Date startDate)
Model:
public String doTemplateUI(Model model){//DispatcherServlet调用
model.addAttribute("name","default");
return "default";
}
ModelAndView:
public ModelAndView do2(ModelAndView mv){
mv.addObject("name","json");
mv.addObject("state",true);
mv.setViewName("default");
return mv;
}
返回类型
pojo,map,list
//基于此对象将pojo转化为json字符串对象
ObjectMapper om=new ObjectMapper();
String jsonStr=om.writeValueAsString(rr);
response.setContentType("text/html;charset=utf-8");
PrintWriter pw=response.getWriter();
pw.print(jsonStr);
跨域
JSONP方式
//http://xxx.com/web/testJSONP1?callback=hello&xxx=xxx...
$.ajax({
type: "get",
url: "http://xxx.com/web/testJSONP1"
dataType: "jsonp", //如果是注解@CrossOrigin方式跨域不需要写
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名,一般默认callback
jsonpCallback:"hello",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(data){
alert(data.itemId+" "+data.itemDesc);
}
});
@RequestMapping("/web/testJSONP1")
public String json(String callback){
//输出接收的callback=hello
ItemDesc item=new ItemDesc();
item.setItemId(100L).setItemDesc("desc属性");
String json= ObjectMapperUtil.toJSON(item);
//http://xxx.com/web/testJSONP1?callback=hello&_=1610351374654
return callback+"("+json+")";//hello({itemId:xxx,itemDesc:xxx})
}
//封装上述代码
@RequestMapping("/web/testJSONP2")
public JSONPObject json2(String callback){
ItemDesc item=new ItemDesc();
item.setItemId(100L).setItemDesc("desc属性");
JSONPObject jsonpObject=new JSONPObject(callback, item);
return jsonpObject;
}
@CrossOrigin方式
@RequestMapping("/web/testJSONP3")
@CrossOrigin//(value=http://www.sso.com)//参数只允许该跨域
public ItemDesc json3(){
ItemDesc item=new ItemDesc();
item.setItemId(100L).setItemDesc("desc属性");
return item;
}
以上是关于SpringMVC原理操作流程,拦截器,过滤器,参数,跨域的主要内容,如果未能解决你的问题,请参考以下文章