SpringMVC参数注入
1.简单参数注入
1.通过key=value方法注入
前端请求 127.0.0.1:8080/user?username=tom&age=12
后端接收时的参数必须也为username和age
如果参数名不统一,既参数不是username或者age则需要通过注解映射
package com.fs.controller;
import com.fs.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class UserController{
/*通过参数名与请求key相同注入*/
@GetMapping(value = "/user")
public ModelAndView oneWay(String username, Integer age) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
/*通过注解手动映射注入参数*/
/* @GetMapping(value = "/user")
public ModelAndView oneWay(@RequestParam("username") String name, Integer age) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}*/
}
2.通过RestFul风格注入
前端请求 127.0.0.1:8080/user/username/tom/age/12
后端接收时必须使用注解@PathVariable注解
@GetMapping("/user/username/{name}/age/{age}")
public ModelAndView twoWay(@PathVariable("name") String username,@PathVariable("age") Integer age){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
2.自定义对象参数注入
1.通过key=value注入
前端请求 127.0.0.1:8080/user?username=tom&age=12
后端接收时,后端对象必须要包含与前端对象的key相同的属性
@GetMapping("/user")
public ModelAndView twoWay(User user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
class User {
private String username;
private Integer age;
private String sex;
}
3.日期参数注入
1.通过日期注释注入
1.1通过key=value
前端请求 127.0.0.1:8080/user?birthday=2000-8-12
后端接收时,由于系统不能自动区别是否要转化为时间类,所以我们需要通过注解告诉系统
//ps:注释中的pattern代表时间以什么形式显示,必须与前端请求时间格式相同
/*
前端请求127.0.0.1:8080/user?date=2000年8月12日
pattern必须等于"yyyy年MM月dd日"
前端请求127.0.0.1:8080/user?date=2000-8-12
pattern必须等于"yyyy-MM-dd"
*/
@GetMapping("/user")
public ModelAndView threeWay(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
1.2通过RestFul风格(该方法不可以使用yyyy/MM/dd这个格式)
前端请求 127.0.0.1:8080/user/2000-8-12
后端接收时,由于系统不能自动区别是否要转化为时间类,所以我们需要通过注解告诉系统
@GetMapping("/user/{time}")
public ModelAndView threeWay
(@PathVariable("time") @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
2.通过全局的日期转化类注入
@DateTimeFormat是局部的,只针对你标记的那一个变量有效,但是当日期类特别多时,一个个的用局部会特别的麻烦,所以这里引入一套全局的
第一步: 手动编写一个日期转换器类,实现org.springframework.core.convert.converter.Converter接口
public class MyDateConverter implements Converter<String, Date> {
//SpringMVC调用, 给Controller方法的形参绑定数据的时候, 需要进行把String转换Date转换的时候调用,
@Override
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("日期转换异常,日期格式不对,支持日期格式:yyyy-MM-dd");
}
}
}
第二步: 在springMVC的配置文件中, 配置日期转换器
<!-- 自定义参数绑定 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<!-- 指定自己定义的Converter类
内部bean, 只能在conversionService的bean内部有效
-->
<bean class="com.fs.ssm.converter.MyDateConverter"/>
<!--<bean class="com.fs.ssm.converter.MyIntegerConverter"/>-->
</set>
</property>
</bean>
第三步:把转换器服务注册到springmvc的注解驱动
<mvc:annotation-driven conversion-service="conversionService" />
全局转换器与@DateTimeFormat 只能二选一,不能同时使用
这样就可以将以上的时间注释去掉
前端请求 127.0.0.1:8080/user?birthday=2000-8-12
后端接收时,由于系统不能自动区别是否要转化为时间类,所以我们需要通过注解告诉系统
//ps:注释中的pattern代表时间以什么形式显示,必须与前端请求时间格式相同
/*
前端请求127.0.0.1:8080/user?date=2000年8月12日
pattern必须等于"yyyy年MM月dd日"
前端请求127.0.0.1:8080/user?date=2000-8-12
pattern必须等于"yyyy-MM-dd"
*/
@GetMapping("/user")
public ModelAndView threeWay(Date birthday){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello");
return modelAndView;
}
4.json参数注入
SpringMVC对json支持
提供两个注解:
@RequestBody
使用在方法参数前面 把json字符串转换为对象
@ResponseBody
加在方法上, 或者Controller类上 把处理请求的方法的返回值对象转换json格式响应给前端
json依赖: fastJson jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>
public class Student {
private String name;//姓名
private String sex;//性别
private Integer age;//年龄
private Clazz clazz;//班级
}
public class Clazz {
private String grposte;//年级
private String clbum;//班级
}
前端的json格式
{
'name':'张三',
'sex':'男',
'age':'15',
'clazz':
{
'grposte':'八',
'clbum':'六',
},
}
5.Controller方法返回值
-
ModelAndView 存放数据与逻辑视图名
-
自定义的类类型 后台响应给前端的是一个json数据 AJXA AXIOS 对Ajax的封装
AJAX: 异步通信,实现局部刷新
- String 不会配合@ResponseBody, 返回的逻辑视图名
@GetMapping("fun1")
public String fun1(Model model){
//...业务代码
//返回的是一个逻辑视图名, 经过视图解析器,找到对应的物理视图
model.addAttribute("data","wellcome");
return "wellcome"; //经过视图解析器,通过转发的方式,跳转到物理视图
}
配合: “forward : 路径” 转发到指定url 不经过视图解析器, 转发资源可以是视图,也可以是某个处理器的处理方法
@GetMapping("fun2")
public String fun2(){
//把请求转发给fun1()
// return "fun1"; //经过视图解析器,通过转发的方式,跳转到物理视图 文.件[/jsp/fun1.jsp] 未找到
// return "forward:/jsp/wellcome.jsp"; //转发到指定视图, 不经过视图解析器,url必须是完整
//转发到处理器方法
return "forward:/mytest/fun1"; //用户请求fun2 -转发到->fun1-经过视图解析器,转发到->wellcome.jsp
}
配合: “redirect:路径” 重定向到指定url, 不经过视图解析器, 转发资源可以是视图,也可以是某个处理器的处理方法
@GetMapping("fun3")
public String fun3(Model model){
model.addAttribute("data","fun3"); //把数据存在request域
//return "redirect:/jsp/wellcome.jsp"; //重定向到wellcime.jsp
// 请求1: fun3 fun3存储在请求1的request对象
//"redirect:/jsp/wellcome.jsp"; 请求2 <h1>测试成功${data}</h1> 从请求2的request对象中获取
return "redirect:/mytest/fun1"; //重定向到处理器方法
// 请求1 客户端请求fun3 request
// "redirect:/mytest/fun1" fun3 重定向fun1 产生一个新请求: 请求2
}
Controller类上的添加@Controller @ResponseBody, SpringMVC提供一个组合注解, @RestController
@RestController 封装@Controller @ResponseBody
对json进行相关的配置
<mvc:annotation-driven conversion-service="conversionService" >
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<!--ContentType类型:告诉前端,后台响应的application/json,charset: 编码
-->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<!-- 处理responseBody 里面日期类型 -->
<!-- <property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property> -->
<!-- 为null字段时不显示 -->
<property name="serializationInclusion">
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
<!--生成json的key的策略-->
<property name="propertyNamingStrategy">
<bean class="com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy" />
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
PropertyNamingStrategy六种策略
· SNAKE_CASE:示例“userName”转化为“user_name”。
· UPPER_CAMEL_CASE:示例“userName”转化为“UserName”。
· LOWER_CAMEL_CASE:默认模式,示例“userName”转化为“userName”。
· LOWER_CASE:示例“userName”转化为“username”。
· KEBAB_CASE:示例“userName”转化为“user-name”。
</mvc:message-converters>
</mvc:annotation-driven>
PropertyNamingStrategy六种策略
· SNAKE_CASE:示例“userName”转化为“user_name”。
· UPPER_CAMEL_CASE:示例“userName”转化为“UserName”。
· LOWER_CAMEL_CASE:默认模式,示例“userName”转化为“userName”。
· LOWER_CASE:示例“userName”转化为“username”。
· KEBAB_CASE:示例“userName”转化为“user-name”。
· LOWER_DOT_CASE:示例“userName”转化为“user.name”。