03-MVC执行流程-参数解析与Model

devtools/2024/9/23 18:07:54/

重要组件



准备Model,Controller

java">@Configuration
public class WebConfig {@ControllerAdvicestatic class MyControllerAdvice {@ModelAttribute("b")public String bar() {return "bar";}}@Controllerstatic class Controller1 {@ResponseStatus(HttpStatus.OK)  // 添加此注解  这里不测试返回值处理器public ModelAndView foo(@ModelAttribute("u") User user) {System.out.println("Controller1.foo");System.out.println("user = " + user);return null;}}@Datastatic class User {private String name;}
}

准备参数解析器

java">private static HandlerMethodArgumentResolverComposite argumentResolverComposite(AnnotationConfigApplicationContext annotationConfigApplicationContext) {DefaultListableBeanFactory beanFactory = annotationConfigApplicationContext.getDefaultListableBeanFactory();HandlerMethodArgumentResolverComposite resolverComposite = new HandlerMethodArgumentResolverComposite();resolverComposite.addResolvers(// @RequestParam参数解析器       false表示参数上必须有注解才会解析new RequestParamMethodArgumentResolver(beanFactory, false),// @PathVariablenew PathVariableMethodArgumentResolver(),// @RequestHeadernew RequestHeaderMethodArgumentResolver(beanFactory),// @CookieValuenew ServletCookieValueMethodArgumentResolver(beanFactory),// Spring表达式参数解析器new ExpressionValueMethodArgumentResolver(beanFactory),// HttpServletRequestnew ServletRequestMethodArgumentResolver(),// 是否不需要注解@ModelAttribute false:需要  即没有@ModelAttribute的实体参数不解析new ServletModelAttributeMethodProcessor(false),// @RequestBodynew RequestResponseBodyMethodProcessor(CollUtil.newArrayList(new MappingJackson2HttpMessageConverter())),/***是否不需要注解@ModelAttribute true:不需要  即没有@ModelAttribute的实体参数也解析* 注意!!!  这个解析器必须放在@RequestBody解析器后面,否则这个解析器将会优先被使用去解析*/new ServletModelAttributeMethodProcessor(true),/*** @RequestParam 参数解析器 true表示参数上没有注解也会解析* 注意!!!  这个解析器必须放在后面 否则其它类型参数将使用这个解析器解析*/new RequestParamMethodArgumentResolver(beanFactory, true));return resolverComposite;}

测试MVC流程

java">// 1. 准备容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(WebConfig.class);// 2. 准备RequestMappingHandlerAdapter  测试:获取模型工厂并获取初始化时配置在ControllerAdvice中的模型数据
RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter();
requestMappingHandlerAdapter.setApplicationContext(applicationContext);
requestMappingHandlerAdapter.afterPropertiesSet();
Method getModelFactoryMethod = RequestMappingHandlerAdapter.class.getDeclaredMethod("getModelFactory", HandlerMethod.class, WebDataBinderFactory.class);
getModelFactoryMethod.setAccessible(true);// 3. 准备请求
MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
mockHttpServletRequest.setParameter("name", "zhoujunlin");
ServletWebRequest servletWebRequest = new ServletWebRequest(mockHttpServletRequest);// 4. 准备servletInvocableHandlerMethod
ServletInvocableHandlerMethod servletInvocableHandlerMethod = new ServletInvocableHandlerMethod(new Controller1(), Controller1.class.getDeclaredMethod("foo", WebConfig.User.class));
// 这里没有特殊参数绑定  入参传null
ServletRequestDataBinderFactory servletRequestDataBinderFactory = new ServletRequestDataBinderFactory(null, null);
servletInvocableHandlerMethod.setDataBinderFactory(servletRequestDataBinderFactory);
servletInvocableHandlerMethod.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer());
servletInvocableHandlerMethod.setHandlerMethodArgumentResolvers(argumentResolverComposite(applicationContext));
// 暂不研究返回值处理器// 5. 准备ModelAndViewContainer容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();// 6. 获取模型工厂并初始化模型数据
ModelFactory modelFactory = (ModelFactory) getModelFactoryMethod.invoke(requestMappingHandlerAdapter, servletInvocableHandlerMethod, servletRequestDataBinderFactory);
modelFactory.initModel(servletWebRequest, modelAndViewContainer, servletInvocableHandlerMethod);// 7. 方法执行
servletInvocableHandlerMethod.invokeAndHandle(servletWebRequest,modelAndViewContainer);System.out.println("modelAndViewContainer.getModel() = " + modelAndViewContainer.getModel());// 8. 关闭容器
applicationContext.close();

http://www.ppmy.cn/devtools/22814.html

相关文章

安卓手机APP开发__媒体开发部分__用户界面定制

安卓手机APP开发__媒体开发部分__用户界面定制 目录 最佳实践 播放/暂停按钮 监听状态的更新 处理可用的指令 Media3提供了一个默认的播放器视图,这个视图提供了一些定制化的选项。 对于任何进一步的定制,APP开发者都期望实现他们的自己的用户界面的…

Power BI:如何将文件夹批量Excel(多sheet页)文件导入?

故事背景: 业务同事想用Power BI分析近两年市场费用。 数据源全部是Excel文件,并且以每月一个Excel文件的方式,统一存放到同一文件夹下面。 重点,每张Excel文件会有多张sheet页,用区分每家分公司的费用信息。 目前…

UDP数据报套接字编程

UDP数据报套接字编程 DatagramSocket API DatagramSocket,是UDP Socket,用于发送和收 UDP 数据报。使用这个类,表示一个 socket 对象。一个 socket 对象只能跟一台主机进行通信。在操作系统中,把这个 socket 对象当成一个文件来…

SpringMVC基础篇(四)

文章目录 1.视图1.基本介绍1.视图介绍2.为什么需要自定义视图 2.自定义视图实例1.思路分析2.代码实例1.view.jsp2.接口3.配置自定义视图解析器springDispatcherServlet-servlet.xml4.自定义视图MyView.java5.view_result.jsp6.结果展示 3.自定义视图执行流程4.自定义视图执行流…

CSS基础:4类组合选择器以及5个注意事项

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生,一枚程序媛,感谢关注。回复 “前端基础题”,可免费获得前端基础 100 题汇总,回复 “前端工具”,可获取 Web 开发工具合…

Matlab实现CNN-BiLSTM模型,对一维时序信号进行分类

1、利用Matlab2021b训练CNN-BiLSTM模型,对采集的一维时序信号进行分类二分类或多分类 2、CNN-BiLSTM时序信号多分类执行结果截图 训练进度: 网络分析: 指标变化趋势: 代码下载方式(代码含数据集与模型构建&#xff0…

MATLAB初学者入门(23)—— 旅行商问题(TSP)优化

旅行商问题(TSP, Traveling Salesman Problem)是一个经典的优化问题,要求找到一个最短的路线,使得旅行商从一个城市出发,经过所有城市一次后,回到原出发点。这是一个NP难问题,在数学优化和计算机…

2024 JAVA Tinypng压缩图片,超级简单!!!

一、打开官网,注册账号,获取秘钥(每个月500张免费) 1.打开官网,注册账号 TinyPNG – Compress WebP, PNG and JPEG images intelligently 2.登录后,点击账号名字,找到如图所示 3.找到API&…