• springmvc


    目录

    SpringMVC相关概念

    SpringMVC如何接收请求、数据和响应结果

    请求参数

    响应

    RESTful风格及其使用

    异常处理

    拦截器


    SpringMVC相关概念

    SpringMVC 是隶属于 Spring 框架的一部分,主要是用来进行 Web开发, 基于 Java 实现 MVC 模型的轻量级 Web 框架,是对Servlet进行了封装, 使用简单、开发便捷 ( 相比于 Servlet), 其主要的作用就是用来接收前端发过来的请求和数据然后经过处理并将处理的结果响应给前端。
            之前的web程序因为是同步调用,性能慢慢的跟不上需求,所以异步调用慢慢的走到了前台,是现在比较流行的一种处理方式,前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成 json 格式进行返回,SpringMVC 主要 负责的就是
    • controller如何接收请求和数据
    • 如何将请求和数据转发给业务层
    • 如何将响应数据转换成json发回到前端

    SpringMVC如何接收请求、数据和响应结果

    一次性工作

    1、创建工程,设置服务器,加载工程
    2、导入坐标 javax . servlet - api,spring - webmvc和build插件 tomcat7 - maven - plugin
    3、创建 web 容器启动类,加载 SpringMVC 配置,并设置 SpringMVC 请求拦截路径
    4、SpringMVC核心配置类替换 web.xml(设置配置类,扫描controller 包,加载 Controller 控制器 bean
    1. //web容器配置类
    2. //AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
    3. public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    4. //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
    5. protected WebApplicationContext createServletApplicationContext() {
    6. //初始化WebApplicationContext对象
    7. AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    8. //加载指定配置类
    9. ctx.register(SpringMvcConfig.class);
    10. return ctx;
    11. }
    12. //设置由springmvc控制器处理的请求映射路径,即SpringMVC拦截哪些请求
    13. protected String[] getServletMappings() {
    14. return new String[]{"/"};
    15. }
    16. //加载spring配置类
    17. protected WebApplicationContext createRootApplicationContext() {
    18. AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    19. ctx.register(SpringConfig.class);
    20. return ctx;
    21. }
    22. }

    多次工作
    5、定义处理请求的控制器类
    6、定义处理请求的控制器方法,并配置映射路径( @RequestMapping )与返回 json 数据
    @ResponseBody
    1. //定义表现层控制器bean
    2. @Controller
    3. public class UserController {
    4. //设置当前方法映射路径为/save,即外部访问路径
    5. @RequestMapping("/save")
    6. //设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
    7. @ResponseBody
    8. public String save(){
    9. System.out.println("user save ...");
    10. return "{'info':'springmvc'}";
    11. }

    如何让 Spring SpringMVC分开加载各自的内容?使用精准范围扫描或排除扫描
    • SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
    • Spring控制的bean包括业务bean(Service)和功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer)
    1. @Configuration
    2. //@ComponentScan({"com.itheima.service","com.itheima.dao"})
    3. //设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
    4. //excludeFilters属性:设置扫描加载bean时,排除的过滤规则
    5. //type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
    6. //classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
    7. @ComponentScan(value="com.itheima",
    8. excludeFilters = @ComponentScan.Filter(
    9. type = FilterType.ANNOTATION,
    10. classes = Controller.class
    11. )
    12. )
    13. public class SpringConfig {
    14. }

    请求参数

    建议为不同模块设置模块名作为请求路径前置以减少命名冲突

    • 当类上和方法上都添加了@RequestMapping注解,前端发送请求的时候,要和两个注解的value 值相加匹配才能访问到。
    • @RequestMapping注解value属性前面加不加/都可以

    1、普通参数:使用@RequestParam注解解决地址参数名与形参变量名不同的问题

    2、POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数,否则无法封装

    3、数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数

    4、集合保存普通参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据

    5、json数据传输参数:先开启json数据类型自动转换 @EnableWebMvc,再使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据

    1. 请求数据
    2. [
    3. {"name":"itcast","age":15},
    4. {"name":"itheima","age":12}
    5. ]
    6. 后台接收
    7. @RequestMapping("/listPojoParamForJson")
    8. @ResponseBody
    9. public String listPojoParamForJson(@RequestBody List list){
    10. System.out.println("list pojo(json)参数传递 list ==> "+list);
    11. return "{'module':'list pojo for json param'}";
    12. }

    6、日期类型参数:SpringMVC默认支持的字符串转日期的格式为yyyy/MM/dd。传递其他格式需要使用@DateTimeFormat

    1. @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
    2. @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2

    响应

    响应页面:不加 @ResponseBody
    响应数据:加 @ResponseBody, 写在类上就是该类下的所有方法都有 @ReponseBody 功能
            文本数据:方法的返回值为字符串,会将其作为文本内容直接响应给前端
            json数据:方法的返回值为对象,会将对象转换成 JSON 响应给前端

    RESTful风格及其使用

    REST( Representational State Transfer ),表现形式状态转换 ,是一种软件架构风格,可以降低开发的复杂性,提高系统的可伸缩性,后期的应用也是非常广 泛, rest 隐藏资源的访问行为,无法通过地址得知对资源是何种操作,也使书写简化,REST 中规定 GET/POST/PUT/DELETE 针对的是查询 / 新增 / 修改 /删除,根据 REST 风格对资源进行访问称为 RESTful
    1. @RestController //使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
    2. @RequestMapping("/books")
    3. public class BookController {
    4. // @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
    5. @DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
    6. public String delete(@PathVariable Integer id){
    7. System.out.println("book delete..." + id);
    8. return "{'module':'book delete'}";
    9. }

    异常处理

    所有的异常均抛出到表现层进行处理,SpringMVC提供了异常处理器,集中的、统一的处理项目中出现的异常

    1. //@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
    2. @RestControllerAdvice
    3. public class ProjectExceptionAdvice {
    4. //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    5. @ExceptionHandler(Exception.class)
    6. public void doException(Exception ex){
    7. System.out.println("嘿嘿,异常你哪里跑!")
    8. return new Result(666,null,"嘿嘿,异常你哪里跑!");
    9. }
    10. }

    异常解决方案:

    1. 先通过自定义异常,完成 BusinessException SystemException 的定义
    2. 将其他异常包装成自定义异常类型
    1. //模拟业务异常,包装成自定义异常
    2. if(id == 1){
    3. throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
    4. }
    5. //模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
    6. try{
    7. int i = 1/0;
    8. }catch (Exception e){
    9. throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
    10. }
    3. 在异常处理器类中对不同的异常进行处理
    1. //@ExceptionHandler用于设置当前处理器类对应的异常类型
    2. @ExceptionHandler(SystemException.class)
    3. public Result doSystemException(SystemException ex){
    4. //记录日志
    5. //发送消息给运维
    6. //发送邮件给开发人员,ex对象发送给开发人员
    7. return new Result(ex.getCode(),null,ex.getMessage());
    8. }

    拦截器

    拦截器( Interceptor )是一种动态拦截方法调用的机制,在 SpringMVC 中动态拦截控制器方法
    的执行,以针对 SpringMVC的访问进行增强;
    拦截器中的 preHandler 方法,如果返回 true, 则代表放行,会执行原始
    Controller 类中要请求的方法,如果返回 false ,则代表拦截,后面的就不会再执行了

     

     

     

    步骤一:创建拦截器类

    1. @Component
    2. //定义拦截器类,实现HandlerInterceptor接口
    3. //注意当前类必须受Spring容器控制
    4. public class ProjectInterceptor implements HandlerInterceptor {
    5. @Override
    6. //原始方法调用前执行的内容
    7. //返回值类型可以拦截控制的执行,true放行,false终止
    8. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    9. String contentType = request.getHeader("Content-Type");
    10. HandlerMethod hm = (HandlerMethod)handler;
    11. System.out.println("preHandle..."+contentType);
    12. return true;
    13. }
    14. @Override
    15. //原始方法调用后执行的内容
    16. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    17. System.out.println("postHandle...");
    18. }
    19. @Override
    20. //原始方法调用完成后执行的内容
    21. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    22. System.out.println("afterCompletion...");
    23. }
    24. }

    步骤二:配置拦截器类

    1. @Configuration
    2. @ComponentScan({"com.itheima.controller"})
    3. @EnableWebMvc
    4. //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
    5. public class SpringMvcConfig implements WebMvcConfigurer {
    6. @Autowired
    7. private ProjectInterceptor projectInterceptor;
    8. @Autowired
    9. private ProjectInterceptor2 projectInterceptor2;
    10. @Override
    11. public void addInterceptors(InterceptorRegistry registry) {
    12. //配置多拦截器
    13. registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    14. registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
    15. }
    16. }

     

    当配置多个拦截器时,形成拦截器链,拦截器链的运行顺序参照拦截器添加顺序为准
    当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
    当拦截器运行中断,仅运行配置在前面的拦截器的 afterCompletion 操作

     

     

  • 相关阅读:
    基础1:JS的原型和原型链究竟
    k8s审计
    细说react源码中的合成事件
    爱了爱了,Alibaba顶级MySQL调优手册到手,加薪妥了
    (防坑)Alphafold 非docker 安装指南
    初学C语言有什么建议?
    Lock使用及效率分析(C#)
    1.1 git常规操作
    TSINGSEE青犀AI智能分析算法助力小区规范整改:楼道杂物堆放检测
    git 回退过程记录
  • 原文地址:https://blog.csdn.net/roycer1/article/details/127822895