跳转到目录
如何在Controller中获取(前端传过来的数据)请求中的信息呢?
跳转到目录
@Controller
@RequestMapping("/request")
public class HandleRequestController {
// 也可以通过DI注入的方式,因为Controller是单例的,多线程不安全(不建议使用)
@Autowired
private ServletContext servletContext;
// 可以通过参数来操作Servlet的api
@RequestMapping("/test1")
public void test1(HttpServletRequest request, HttpServletResponse responser, HttpSession session) {
System.out.println(request.getParameter("username"));
System.out.println(request);
System.out.println(responser);
System.out.println(session);
System.out.println(this.servletContext);
}
}
跳转到目录
@Controller
@RequestMapping("/request")
public class HandleRequestController {
// 获取请求参数,保证请求参数名称和Controller方法的形参(入参)同名;
// 这样就可以获得请求的参数内容; 名字不同,得不到
@RequestMapping("/test2")
public void test2(String username, int age) {
System.out.println("username:" + username);
System.out.println("age:" + age);
}
// 如果请求参数名称和形参名称不同 ==> 使用RequestParam注解
// 使用@RequestMapping注解后,名字不同,也可以获取,请求参数的内容
@RequestMapping("/test3")
public void test3(@RequestParam("name") String username, @RequestParam(value = "age") Integer age) {
System.out.println("username:" + username);
System.out.println("age:" + age);
}
}
跳转到目录
在web.xml中配置
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
<init-param>
<param-name>forceRequestEncodingparam-name>
<param-value>trueparam-value>
init-param>
<init-param>
<param-name>forceResponseEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
跳转到目录
/delete?id=11 以前的方式
/delete/11 RESTfull方式
@PathVariable: 可以将URL中占位符绑定到方法的形参中
// 请求地址为 http://localhost:8080/request/delete/3
@RequestMapping("delete/{id}")
public void test4(@PathVariable("id") Long id){
System.out.println(id);
}
跳转到目录
// 接受一个参数有多个值的情况
// 批量删除; /batchDelete?ids=10&ids=20&ids=30
// 使用数组: 可以直接接收传递的多个参数
@RequestMapping("/batchDelete")
public void batchDelete(Long[] ids){
System.out.println(Arrays.asList(ids));
}
// 使用集合List: 不能直接接受,可以在对象中存在一个集合
@RequestMapping("/batchDelete2")
public void batchDelete2(FormBean fb){
System.out.println(fb.getIds());
}
//操作一个参数有多个值的情况,一般直接使用数组接受就可以了,或者使用JavaBean对象来封装数据.
//把数据直接封装到JavaBean对象
@RequestMapping("/test4")
public void test4(User u) {
System.out.println(u);
}
测试如下:
默认会把符合类型参数共享到视图中,共享的key名为参数类型首字母小写; 如果要修改共享数据的key名; 使用ModelAttribute
注解
跳转到目录
ModelAttribute注解
@RequestMapping("/zy1")
public String test1(User u){
System.out.println(u);
return "welcome";
}
@RequestMapping("/zy2")
public String test2(@ModelAttribute("zyuser") User u){
System.out.println(u);
return "welcome";
}
welcome.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>welcometitle>
head>
<body>
retult:
${user}<br>
${zyuser}<br>
body>
html>
// 操作其他的请求信息
@Controller
@RequestMapping("/other")
@SessionAttributes("errorMsg")
public class OtherController {
// 获取请求头中的User-Agent和Cookie信息
// 以前的方式
@RequestMapping("zy1")
public void test0(HttpServletRequest request){
String header = request.getHeader("User-Agent");
String jsessionid = request.getHeader("Cookie");
System.out.println(header);
System.out.println(jsessionid);
}
// 现在的方式
@RequestMapping("zy2")
public void test1(@RequestHeader("User-Agent") String userAgent, @CookieValue("JSESSIONID") String cookieName){
System.out.println("User-Agent:" + userAgent);
System.out.println("cookieName" + cookieName);
}
// 操作HttpSession;
// 默认情况下Model数据是放到request中共享的,如果我想在session共享---->SessionAttributes注解
@RequestMapping("/zy3")
public String test2(Model model){
model.addAttribute("errorMsg", "错误信息!");
//默认肯定不能共享数据的,因为是重定向;之前讲过的那个Flash共享也仅仅只是在Controller之间共享
return "redirect:/abc.jsp";
}
}
abc.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
result:
${requestScope.errorMsg}<br>
${sessionScope.errorMsg}<br>
${errorMsg}<br>
body>
html>
跳转到目录
SpringMVC通过反射机制对目标处理方法的签名进行分析,将请求信息绑定到处理方法的形参中,数据绑定的核心组件是DataBinder类。
数据绑定流程:
1、框架把ServletRequest对象和请求参数传递给DataBinder ;
2、DataBinder 首先调用Spring Web环境中的ConversionService组件,进行数据类型转换和格式化等操作,将ServletRequest中的信息填充到形参对象中;
3、DataBinder 然后调用Validator组件对已经绑定了请求消息数据的形参对象进行数据合法性校验;
4、DataBinder 最后输出数据绑定结果对象BindingResult.
BindingResult包含了已完成数据绑定的形参对象和校验错误信息对象。
最终SpringMVC框架会把BindingResult中的数据,分别赋给相应的处理方法。
对象名.属性名
传参方式。此时需要我们来对象数据设置绑定规则。
InitBinder注解:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
由@InitBinder注解标注的方法,可以对WebDataBinder对象进行初始化。而WebDataBinder是DataBinder的子类,用于完成由请求参数到JavaBean的属性绑定。
注意点:
@InitBinder标注的方法不能有返回值,它必须声明为void。
@InitBinder标注的方法的参数通常是WebDataBinder.
input.html
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
<form action="/save" method="POST">
狗狗姓名:<input type="text" name="dog.name"/><br/>
狗狗年龄:<input type="text" name="dog.age"/><br/>
猫猫姓名:<input type="text" name="cat.name"/><br/>
猫猫年龄:<input type="text" name="cat.age"/><br/>
<input type="submit" value="提交"/>
form>
body>
html>
Java代码
// 处理多个对象的封装
@Controller
public class MultiObjectParamController {
/*
需要把表单数据封装到多个对象中去,如果各个对象都有相同的属性,此时要出问题.
不知道该把哪一个参数封装到哪一个对象中去.
*/
// 参数-->对象,封装规则需要我们来设置
// 把以dog.开头的参数封装到dog对象中
@InitBinder("dog") // 自定义数据绑定注册,用于将请求参数转换到对应的对象的属性中去
public void initBinderDogyType(WebDataBinder binder){
binder.setFieldDefaultPrefix("dog.");
}
@InitBinder("cat")
public void initBinderCatType(WebDataBinder binder){
binder.setFieldDefaultPrefix("cat.");
}
@RequestMapping("/save")
public ModelAndView save(Cat cat, Dog dog){
System.out.println(cat);
System.out.println(dog);
return null;
}
}
跳转到目录
Jackson 是一个Java开源的JSON工具库,性能很高,可以轻松将Java对象转换成Json对象xml文档,同样也可以将json、xml转换成Java对象
首先导入Jackson的Maven依赖
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.10version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.10version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.10version>
dependency>
// 处理JSON
@Controller
@RequestMapping("/json")
public class HandleJsonController {
/*
处理JSON的注解:
ResponseBody: 处理响应,把对象转换为JSON字符串.
贴到方法上:只针对当前方法做JSON处理.
贴到类上 : 会对当前类中所有的方法做JSON处理.
RestController = Controller + ResponseBody
RequestBody: 处理请求,用于读取HTTP请求的内容,把JSON格式的请求数据封装成对象.
一般的请求的数据格式:
application/x-www-form-urlencoded: 传统的key-value格式,处理起来非常方便. 不需要RequestBody都可以,贴上也可以.
application/multipart:文件上传的请求,SpringMVC装设设计模式,.既能处理文件上传,也能处理普通表单数据.
application/json: 参数是JSON格式的,此时必须使用RequestBody.
*/
// 把单个对象/Map转换为JSON格式
@RequestMapping("/test1")
@ResponseBody
public User test1() {
User u = new User();
u.setUsername("桂朝阳");
u.setAge(22);
return u;
}
// 把集合转为JSON格式
@RequestMapping("/test2")
@ResponseBody
public List<User> test2() {
User u = new User();
u.setUsername("桂阳");
u.setAge(22);
return Arrays.asList(u, u, u);
}
注意 : Jackson包导入后可能没有加载上,后台会报500错误; 注意看这个地方是否有jar包
跳转到目录
方式一
@Controller
@RequestMapping("/date")
public class HandleDateController {
// 从前台--->后台传递参数: String ---> java.util.Date // http://localhost:8080/date/test1?d=2010-11-1
@RequestMapping("/test1")
public ModelAndView test1(@DateTimeFormat(pattern = "yyyy-MM-dd") Date d){
System.out.println(d);
return null;
}
}
方式二
@Data
public class User {
private Long id;
private String username;
private Integer age;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date hiredate;
}
@Controller
@RequestMapping("/date")
public class HandleDateController {
// http://localhost:8080/date/test1?id=2&username=zy&age=23&hiredate=2020-2-1
@RequestMapping("/test2")
public ModelAndView test2(User user){
System.out.println(user);
return null;
}
}
方式三
@ControllerAdvice注解
@Data
public class User {
private Long id;
private String username;
private Integer age;
private Date hiredate;
}
@ControllerAdvice
public class DateFormatAdvice {
//如果不想每次都在Date类型上@DateTimeFormat
@InitBinder
public void initBinderDateType(WebDataBinder binder) {
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.applyPattern("yyyy-MM-dd");
binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(sdf, true));
}
}
// 处理JSON
@Controller
@RequestMapping("/json")
public class HandleJsonController {
@RequestMapping("/test3")
@ResponseBody
public User test3(){
User user = new User();
user.setUsername("will");
user.setAge(82);
user.setHiredate(new Date());
return user;
}
}