Spring MVC

0 阅读6分钟
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

知识点1:@Controller

| 名称 | @Controller | | --- | --- | | 类型 | 类注解 | | 位置 | SpringMVC控制器类定义上方 | | 作用 | 设定SpringMVC的核心控制器bean |

知识点2:@RequestMapping

| 名称 | @RequestMapping | | --- | --- | | 类型 | 类注解或方法注解 | | 位置 | SpringMVC控制器类或方法定义上方 | | 作用 | 设置当前控制器方法请求访问路径 | | 相关属性 | value(默认),请求访问路径 |

知识点3:@ResponseBody

| 名称 | @ResponseBody | | --- | --- | | 类型 | 类注解或方法注解 | | 位置 | SpringMVC控制器类或方法定义上方 | | 作用 | 设置当前控制器方法响应内容为当前返回值,无需解析 |

Spring已经多把SpringMVC的controller类也给扫描到,所以针对这个问题该如何解决?

针对上面的问题,解决方案也比较简单,就是:

  • 加载Spring控制的bean的时候排除掉SpringMVC控制的备案

具体该如何排除,有两种方式来解决:

  • 方式一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包中的bean
  • 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
  • 方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中[了解即可]

@RequestParam

| 名称 | @RequestParam | | --- | --- | | 类型 | 形参注解 | | 位置 | SpringMVC控制器方法形参定义前面 | | 作用 | 绑定请求参数与处理器方法形参间的关系 | | 相关参数 | required:是否为必传参数
defaultValue:参数默认值 |

小结

SpringMVC接收JSON数据的实现步骤为:

(1)导入jackson包

(2)使用PostMan发送JSON数据

(3)开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解

(4)Controller方法的参数前添加@RequestBody注解

知识点1:@EnableWebMvc

| 名称 | @EnableWebMvc | | --- | --- | | 类型 | ==配置类注解== | | 位置 | SpringMVC配置类定义上方 | | 作用 | 开启SpringMVC多项辅助功能 |

知识点2:@RequestBody

@RequestBody与@RequestParam区别
●区别
○@RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
○@RequestBody用于接收json数据【application/json】
●应用
○后期开发中,发送json格式数据为主,@RequestBody应用较广
○如果发送非json格式数据,选用@RequestParam接收请求参数
知识点1:@DateTimeFormat

| 名称 | @DateTimeFormat | | --- | --- | | 类型 | ==形参注解== | | 位置 | SpringMVC控制器方法形参前面 | | 作用 | 设定日期时间型数据格式 | | 相关属性 | pattern:指定日期时间格式字符串 |

内部实现原理
讲解内部原理之前,我们需要先思考个问题:
●前端传递字符串,后端使用日期Date接收
●前端传递JSON数据,后端使用对象接收
●后台需要的数据类型有很多中
●前端传递字符串,后端使用Integer接收
●在数据的传递过程中存在很多类型的转换
问:谁来做这个类型转换?
答:SpringMVC
问:SpringMVC是如何实现类型转换的?
答:Converter接口
在框架中,有一个类型转换接口
●Converter接口

/**
*	S: the source type
*	T: the target type
*/
public interface Converter<S, T> {
    @Nullable
    //该方法就是将从页面上接收的数据(S)转换成我们想要的数据类型(T)返回
    T convert(S source);
}

| 名称 | @RequestBody | | --- | --- | | 类型 | ==形参注解== | | 位置 | SpringMVC控制器方法形参定义前面 | | 作用 | 将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次 |

注意:Converter所属的包为****org.springframework.core.convert.converter

  • Converter接口的实现类

框架中有提供很多对应Converter接口的实现类,用来实现不同数据类型之间的转换。前面咱们其实一直在使用这个类型转换,如:

  • 请求参数年龄数据(String→Integer)
  • json数据转对象(json → POJO)
  • 日期格式转换(String → Date)

==注意:SpringMVC的配置类把@EnableWebMvc当做标配配置上去,不要省略==

//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}

RESTful入门案例,

我们需要学习的内容如下:

(1)设定Http请求动作(动词)

@RequestMapping(value="",==method== = RequestMethod.==POST|GET|PUT|DELETE==)

(2)设定请求参数(路径变量)

@RequestMapping(value="/users/=={id}==",method = RequestMethod.DELETE)

@ReponseBody

public String delete(==@PathVariable== Integer ==id==){

}

知识点1:@PathVariable

| 名称 | @PathVariable | | --- | --- | | 类型 | ==形参注解== | | 位置 | SpringMVC控制器方法形参定义前面 | | 作用 | 绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应 |

关于接收参数,我们学过三个注解@RequestBody、@RequestParam、@PathVariable,这三个注解之间的区别和应用分别是什么?

  • 区别

    • @RequestParam用于接收url地址传参或表单传参
    • @RequestBody用于接收json数据
    • @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  • 应用

    • 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数
    • 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
@RestController //@Controller + ReponseBody
@RequestMapping("/books")

知识点1:@RestController

| 名称 | @RestController | | --- | --- | | 类型 | ==类注解== | | 位置 | 基于SpringMVC的RESTful开发控制器类定义上方 | | 作用 | 设置当前控制器类为RESTful风格,
等同于@Controller与@ResponseBody两个注解组合功能 |

知识点2:@GetMapping @PostMapping @PutMapping @DeleteMapping

| 名称 | @GetMapping @PostMapping @PutMapping @DeleteMapping | | --- | --- | | 类型 | ==方法注解== | | 位置 | 基于SpringMVC的RESTful开发控制器方法定义上方 | | 作用 | 设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,
例如@GetMapping对应GET请求 | | 相关属性 | value(默认):请求访问路径 |

异常处理器

2.2.2 @RestControllerAdvice注解介绍

  • 名称:@RestControllerAdvice
  • 类型:==类注解==
  • 位置:Rest风格开发的控制器增强类定义上方
  • 作用:为Rest风格开发的控制器类做增强
  • 说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能

2.2.3 @ExceptionHandler注解介绍

  • 名称:@ExceptionHandler
  • 类型:==方法注解==
  • 位置:专用于异常处理的控制器方法上方
  • 作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行
  • 说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常

拦截器和过滤器的区别

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
    @Component //注意当前类必须受Spring容器控制
    //定义拦截器类,实现HandlerInterceptor接口
    public class ProjectInterceptor implements HandlerInterceptor {
        @Override
        //原始方法调用前执行的内容
        //返回值类型可以拦截控制的执行,true放行,false终止
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle..."+contentType);
            return true;
        }
    
        @Override
        //原始方法调用后执行的内容
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle...");
        }
    
        @Override
        //原始方法调用完成后执行的内容
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("afterCompletion...");
        }
    }