3.3 bean加载控制
因为功能不同,如何避免Spring错误加载到SpringMVC的bean?
针对上面的问题,解决方案也比较简单,就是
:
- 加载Spring控制的bean的时候排除掉SpringMVC控制的bean
具体该如何排除:
- 方式一:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等;
@Configuration
@ComponentScan({"com.itheima.service","comitheima.dao"})
public class SpringConfig {
}
说明:上述只是通过例子说明可以精确指定让Spring扫描对应的包结构,真正在做开发的时候,因为Dao最终是交给MapperScannerConfigurer对象来进行扫描处理的,我们只需要将其扫描到service包即可。
- 方式二:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包中的bean;
@Configuration
@ComponentScan(value="com.itheima",
excludeFilters=@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
excludeFilters属性:设置扫描加载bean时,排除的过滤规;
type
属性:设置排除规则,当前使用按照
bean
定义时的注解类型进行排除;
ANNOTATION
:按照注解排除;
classes
属性:设置排除的具体注解类,当前设置排除
@Controller
定义的
bean。
如何测试controller类已经被排除掉了?
public class App{
public static void main (String[] args){
AnnotationConfigApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println(ctx.getBean(UserController.class));
}
}
如果被排除了,该方法执行就会报
bean
未被定义的错误
![](https://img-blog.csdnimg.cn/033815eb174f4aaabea685e22c190a70.png)
注意
:
测试的时候,需要把
SpringMvcConfig
配置类上的
@ComponentScan
注解注释掉,否则不会
报错
简化开发:Spring
还提供了一种更简单的配置方式,可以不用再创建AnnotationConfigWebApplicationContext对象,不用手动
register
对应的配置类,如何实现
?
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
- 方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中[了解即可]。
知识点:@ComponentScan
3.4 请求与响应
3.4.1 设置请求映射路径
知识点:@RequestMapping
3.4.2 get请求与post请求发送普通参数
GET
发送单个参数
发送请求与参数
:
http://localhost/commonParam?name=itcast
接收参数:
@Controller
public class UserController {
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name){
System.out.println("普通参数传递 name ==> "+name);
return "{'module':'commonParam'}";
}
}
GET
发送多个参数
普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
发送请求与参数:
http://localhost/commonParam?name=itcast&age=15
接收参数:
@Controller
public class UserController {
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'commonParam'}";
}
}
GET
请求中文乱码
Tomcat8.5
以后的版本已经处理了中文乱码的问题,但是
IDEA
中的Tomcat插件目前只到
Tomcat7
,所以需要修改
pom.xml
来解决
GET
请求中文乱码问题
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port><!--tomcat端口号-->
<path>/</path> <!--虚拟目录-->
<uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
</configuration>
POST
发送参数
普通参数:from表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数
发送请求与参数:
接收参数:
和
GET
一致,不用做任何修改
POST
请求中文乱码
解决方案
:
配置过滤器
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
3.5 五种类型参数传递
常见的参数种类有
:
- 普通参数
- POJO类型参数
- 嵌套POJO类型参数
- 数组类型参数
- 集合类型参数
3.5.1 普通参数
- 普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数。
如果形参与地址参数名不一致该如何解决
?
解决方案
:
使用
@RequestParam
注解
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestPaam("name") String
userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
注意
:
写上
@RequestParam
注解框架就不需要自己去解析注入,能提升框架处理性能
3.5.2 POJO数据类型
简单数据类型一般处理的是参数个数比较少的请求,如果参数比较多,那么后台接收参数的时候就比较复杂,这个时候我们可以考虑使用POJO
数据类型。
- POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
注意
:
POJO
参数接收,前端
GET
和
POST
发送请求数据的方式不变。
请求参数
key
的名称要和
POJO
中属性的名称一致,否则无法封装。
3.5.3 嵌套POJO类型参数
- 嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
![](https://img-blog.csdnimg.cn/6d6c991e25dd418b9dcc195da6c2b20f.png)
注意
:
请求参数
key
的名称要和
POJO
中属性的名称一致,否则无法封装
3.5.4 数组类型参数
如果前端需要获取用户的爱好,爱好绝大多数情况下都是多个,如何发送请求数据
和接收数据呢
?
- 数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
3.5.5 集合类型参数
集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
运行会报错,因为
SpringMVC
将
List
看做是一个
POJO
对象来处理,将其创建一个对象并准备把前端的数
据封装到对象中,但是
List
是一个接口无法创建对象,所以报错。
解决方案是
:
使用
@RequestParam
注解
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
- 集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
- 对于简单数据类型使用数组会比集合更简单些。
3.6 JSON数据传递参数
3.6.1 JSON普通数组
步骤1:pom.xml添加依赖
SpringMVC
默认使用的是
jackson
来处理
json
的转换,所以需要在
pom.xml
添加
jackson
依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
步骤2:PostMan发送JSON数据
步骤3:开启SpringMVC注解支持
在
SpringMVC
的配置类中开启
SpringMVC
的注解支持,这里面就包含了将
JSON
转换成对象的功能。
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
步骤4:参数前添加@RequestBody
//使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
步骤5:启动运行程序
3.6.2 JSON对象数据
3.6.3 JSON对象数组
知识点
1
:
@EnableWebMvc
名称
| @EnableWebMvc |
类型 | 配置类注解 |
位置 | SpringMVC配置类定义上方 |
作用 | 开启SpringMVC多项辅助功能 |
知识点
2
:
@RequestBody
名称
| @RequestBody |
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次 |
@RequestBody
与
@RequestParam
区别
区别
- @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
- @RequestBody用于接收json数据【application/json】
应用
- 后期开发中,发送json格式数据为主,@RequestBody应用较广
- 如果发送非json格式数据,选用@RequestParam接收请求参数
3.7 日期型参数传递
知识点
1
:
@DateTimeFormat
类型
| 形参注解 |
位置 | SpringMVC控制器方法形参前面 |
作用 | 设定日期时间型数据格式 |
相关属性 | pattern:指定日期时间格式字符串 |
类型转换器
@EnableWebMvc功能之一:根据类型匹配对应的类型转换器