学习SpringMVC必知必会(3)~springmvc的请求和响应
一、处理器方法响应处理
▷ Controller方法该怎么返回、Controller数据该怎么进行共享
- 返回void/ModelAndView/String
1、Controller方法返回void
//返回void类型,此时可以把Controller方法当做Servlet使用【适合用来下载文件】
@RequestMapping("/test1")
public void test(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求转发
request.getRequestDispatcher("/WEB-INF/views/welcome.jsp").forward(request, response);
//设置共享数据
request.setAttribute("msg", "hello");
//输出json格式
response.setContentType("text/json;charset=utf-8");
response.getWriter().println();
}
2、【常用
】返回ModelAndView
//返回ModelAndView
@RequestMapping("/test3")
public ModelAndView test3() {
ModelAndView mv = new ModelAndView();
//设置视图名称
// mv.setViewName("/WEB-INF/views/welcome.jsp");
mv.setViewName("welcome");
mv.addObject("msg", "返回ModelNAndView");//设置共享数据的key和value
mv.addObject("叩丁狼教育");//设置共享数据的value,此时会把value类型的首字母作为key:string
return mv;
}
3、【常用
】返回String类型(是逻辑视图名称
),参数是Model类型(是共享数据
)
//返回string,逻辑视图名称,此时需要结合参数Model类型 一起使用
@RequestMapping("/test4")
public String test4(Model model) {
//设置共享数据
model.addAttribute("叩丁狼");
model.addAttribute("msg", "教育");
return "welcome";//设置跳转的视图
}
二、请求跳转
- 请求转发、URL重定向、URL重定向共享数据
1、请求转发
//请求转发,浏览器地址栏不变,可以共享请求中的数据
//原理:request.getRequestDispatcher("").forward(request, response);
@RequestMapping("/test5")
public String test5(Model model) {
return "forward:/hello.jsp";//设置跳转的视图
}
2、URL重定向
//重定向,浏览器地址栏改变,不能共享请求中的数据
//原理:request.sendRedirect("");
@RequestMapping("/test6")
public String test6(Model model) {
return "redirect:/hello.jsp";//设置跳转的视图
}
■ 请求资源的路径问题:[总结:访问资源的时候,都使用/开头
]
- 访问资源的时候前面带上/,表示绝对路径,从
根路径
开始去寻找资源 - 访问资源的时候签名不加/,表示相对路径,从
上一级上下文路径
中去寻找资源
✿ 请求转发和URL重定向的选择:
请求转发/URL重定向 | 请求转发 | URL重定向 |
---|---|---|
地址栏改变? | 不会 | 会改变 |
共享数据? | 可以 | 不可以? |
表单重复提交? | 会发生 | 不会发生 |
传统的方式,在url重定向的时候,因为是两次不同的请求,所以不能共享请求中的数据。
在开发中,有时候真的需要重定向跳转后共享数据------------spring3.1开始,提供了Flash属性。
★
只能是从Controller 重定向到 Controller,不能到jsp
3、URL重定向共享数据
//重定向:从a跳转到b
@RequestMapping("/a")
public String a(RedirectAttributes ra) {
ra.addAttribute("msg1", "a传递的数据");
ra.addFlashAttribute("msg2", "msg2");
return "redirect:/response/b";//设置跳转的视图
}
@RequestMapping("/b")
public ModelAndView b(String msg1, @ModelAttribute("msg2") String msg2) {
System.out.println("msg1:" + msg1);
System.out.println("msg2:" + msg2);
return null;
}
重定向共享数据的原理:更大的作用域--session
三、处理器方法参数处理(接收请求参数的处理
)
- 处理器方法的请求参数该怎么携带、请求参数该怎么获取
1、request 和 response 参数
■ 情况一:为了操作Servlet API 对象,此时可以直接以参数形式传递,也可以直接使用DI注入。
@Controller
@RequestMapping("/request")
public class HandlerRequestController {
@Autowired
private ServletContext context;
@RequestMapping("/test1")
public void test(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
System.out.println("request:" + request);
System.out.println("response:" + response);
System.out.println("session:" + session);
System.out.println("ServletContext:" + this.context);
}
}
- request、response、session:建议使用参数
- context 上下文:单例,建议使用属性,注入
▷ 因为Controller(Servlet) 是单例的,线程不安全,一般不用成员变量,
除非要共享的数据,才作为成员变量。
2、简单类型参数
- 处理简单类型的请求参数
■ 获取请求参数:【保证输入的参数和定义的形参名称一致】
//获取请求参数:通过保证请求参数名称和Controller方法定义的形参(入参)同名即可
@RequestMapping("/test2")
public void test2(String username, int age) {
System.out.println(username);
System.out.println(age);
}
■ 获取请求参数:【输入的参数和定义的形参名称不一致】----注解@RequestParam
//获取请求参数:若请求参数和请求参数名称和形参不同----注解@RequestParam
@RequestMapping("/test3")
public void test3(@RequestParam("name") String username, @RequestParam(value="age",required=false) Integer age) {
System.out.println("username:" +username);
System.out.println("age:" + age);
}
3、中文乱码处理
■ 在"全局配置"【web.xml】,添加上编码过滤器
:
<!-- (针对post请求)配置过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 配置初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4、restfull风格传参
- restfull 风格:软件架构风格,严格讲是一种编码风格,充分利用http协议本身的语义,从而提供一些设计原则和约束条件,主要是用来作为客户端和服务端的交互。
- 简洁、有层次、容易实现缓存机制
//restfull风格传递参数
//PathVariable: 可以将url中占位符绑定到方法的形参中
@RequestMapping("/r/{id}")
public ModelAndView rest(@PathVariable("id") Integer id) {
System.out.println("id:" + id);
return null;
}
5、数组和List类型参数
//接收一个参数有很多值的情况
//使用数组:可以直接接收 Long[] ids
//使用List: 不可以直接接收,可以在对象中存在一个集合 List<Long> ids
@RequestMapping("/batchDelete") //batchDelete?ids=10&ids=20&ids=30
public void batchDelete(FormBean fb) {
System.out.println(fb.getIds());
}
★ 操作一个参数有多个值的情况,一般直接使用数组接收即可,或者使用javaBean对象来封装数据。
6、■ 获取请求参数:
JavaBean类型参数【将请求参数封装成一个对象
】
//封装成一个对象
@RequestMapping("/bean") //batchDelete?ids=10&ids=20&ids=30
public void bean(User user) {
System.out.println(user);
}
- 请求参数封装成javaBean对象,浏览器地址栏直接输入参数为对象的属性即可.
✿ 总结处理器方法参数处理:
1、直接把请求参数封装成javaBean对象
2、配置解决中文乱码的过滤器
3、简单类型参数----输入参数名和定义的形参不同-> @ResultParam
4、使用数组
接收多个参数
5、restfull风格传参
四、ModelAttribute
给共享的model数据设置key名,贴在形参上,也可以贴在方法上,
针对复合类型参数,缺省情况下就会放到model中(共享), 缺省的key就是类型首字母小写
- 使用注解 @ModelAttribute,起个别名
//ModelAttribute注解:
/*
*1、给共享的model数据设置key名,贴在形参上,也可以贴在方法上
* 针对复合类型(非简单类型)参数,缺省情况下就会放到model中(共享), 缺省的key就是类型首字母小写
* 2、可以标注一个非请求处理的方法,被标注的方法,每次在请求处理方法之前都会优先被执行[存放多个请求需要共享的数据]
*/
@RequestMapping("/test11")
public String test1(@ModelAttribute("u") User user) {
System.out.println(user);
return "welcome";
}
五、其他请求信息
1、获取请求头 @RequestHeader
@RequestMapping("/test1")
public ModelAndView test1(@RequestHeader("User-Agent") String userAgent) {
System.out.println("test1");
System.out.println("User-Agent:" + userAgent);
return null;
}
2、获取Cookie @CookieValue
@RequestMapping("/test1")
public ModelAndView test1(@RequestHeader("User-Agent") String userAgent, @CookieValue("Webstorm-5895a979") String cName) {
System.out.println("test1");
System.out.println("User-Agent:" + userAgent);
System.out.println("cName:" + cName);
return null;
}
3、操作HttpSession @SessionAttributes
- 默认情况下模型数据是保存到 request 作用域的
@Controller
@RequestMapping("/other")
@SessionAttributes("errMsg")
public class OtherController {
@RequestMapping("/test2")
public String test2(Model model) {
System.out.println("操作session");
model.addAttribute("errMsg", "错误信息");
return "redirect:/hello.jsp";
}
}
六、数据绑定流程
1、框架把 ServletRequest 对象和请求参数传递给 DataBinder
;
2、DataBinder 首先调用 Spring Web 环境中的 ConversionService 组件,进行数据类型转换和格式化等操作,将 ServletRequest 中的信息填充到形参对象中;
3、DataBinder 然后调用 Validator 组件对已经绑定了请求消息数据的形参对象进行数据合法性校验;
4、DataBinder 最后输出数据绑定结果对象 BindingResult
- BindingResult 包含了已完成数据绑定的形参对象和校验错误信息对象
七、多对象封装传参
/*
* 需要吧表单数据封装到多个对象中去,若各个对象有相同的属性时
* 不知道该把哪一个参数封装到哪一个对象
*/
@RequestMapping("/save")
public ModelAndView save(Cat cat, Dog dog) {
System.out.println("提交数据");
System.out.println(cat);
System.out.println(dog);
return null;
}
- input.jsp 传递多个对象的参数时:
<form action="/save" method="post">
猫名:<input type="text" name="name" /><br/>
猫年龄:<input type="text" name="age" /><br/>
狗名:<input type="text" name="name" /><br/>
狗年龄:<input type="text" name="age" /><br/>
<input type="submit" value="提交">
</form>
解决:
input.jsp:加上前缀做区分
<form action="/save" method="post">
猫名:<input type="text" name="cat.name" /><br/>
猫年龄:<input type="text" name="cat.age" /><br/>
狗名:<input type="text" name="dog.name" /><br/>
狗年龄:<input type="text" name="dog.age" /><br/>
<input type="submit" value="提交">
</form>
- 处理器Controller添加方法:
//从参数--> 对象,封装规则需要我们来设置
//自定义数据绑定注册,将请求参数转化成对应对象的属性
@InitBinder("cat")
public void initBinderCat(WebDataBinder binder) {
//设置字段以什么做为前缀
binder.setFieldDefaultPrefix("cat.");
}
@InitBinder("dog")
public void initBinderDog(WebDataBinder binder) {
//设置字段以什么做为前缀
binder.setFieldDefaultPrefix("dog.");
}
八、JSON数据处理
- JSON处理
1、依赖:
- jackson-annotations-2.12.2.jar
- jackson-core-2.12.2.jar
- jackson-databind-2.12.2.jar
2、处理json的注解 @ResponseBody
@RestController
@RequestBody
(1) @ResponseBody: 处理响应,把对象转化成json字符串
- @ResponseBody 处理响应,把对象转化成json字符串
- 贴到方法上:只会针对当前方法做json处理
- 贴到类上:会对当前类中所有方法做json处理
//把单个对象/Map转化成json格式
@RequestMapping("/test1")
@ResponseBody
public User test1() {
User u = new User();
u.setUsername("shan");
u.setAge(18);
return u;
}
//把多个对象转化成json格式
@RequestMapping("/test2")
@ResponseBody
public List<User> test2() {
User u = new User();
u.setUsername("shan");
u.setAge(18);
return Arrays.asList(u, u, u);
}
//返回一个String,默认返回字符串是逻辑视图名称,加上@ResponseBody,当做json格式的数据
@RequestMapping(value="/test3", produces="application/json;charset=utf-8")
@ResponseBody
public String test3() {
return "success, 你好~";
}
(2) @RestController = @Controller + @ResponseBody
(3) @RequestBody
- @RequestBody: 处理请求,用于读取Http请求的内容,把json格式的请求数据封装成对象
- application/x-www-form-urlencoded: 表单提交用得比较多,是传统的key-value格式,处理起来非常方便,无需RequestBody都可以,贴上也可以
- application/multipart: 文件上传的请求,springmvc 装饰设计模式,既可以处理文件上传,也可以处理表单数据
- application/json: 参数是json格式的,此时必须使用RequestBody\
- application/xml
九、日期类型处理
1、前台往后台传参转化为Date类型
★ 时间格式的注解:@DateTimeFormat
- 注意细节:时间Date在util包(java中常用)有,在sql包也有,使用快捷键导包的时候可能会默认自动报错包~
//从前台---->后台传递参数 java.lang.String -> java.util.Date
//请求参数是Date类型
@RequestMapping("/test1")
public ModelAndView test(@DateTimeFormat(pattern = "yyyy-MM-dd")Date date) {
System.out.println("date:" + date);
if(date instanceof Date) {
System.out.println("yes");
}
return null;
}
对象的属性有时间Date类型的,方式一:贴注解 @DateTimeFormat
◆ 方式二:数据绑定的时候处理,通过@InitBinder定义处理时间格式的方法
@InitBinder
public void initBinder(WebDataBinder binder) {
//日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//属性编辑器
binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(sdf, true));
}
让项目中的所有用到时间格式的类都使用到咱定义的处理时间格式的方法,咱将方法抽离出去,定义成一个类,贴上注解处理增强
@ControllerAdvice
,只要抽离的类在ioc的注解驱动扫描范围内,即可~
@ControllerAdvice
public class DateFormateAdvice {
@InitBinder
public void initBinder(WebDataBinder binder) {
//日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//属性编辑器
binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(sdf, true));
}
}
2、jsp中显示时间格式:将欧美时间格式-->中国时间格式
(1)导入jar包[tomcat服务器examples案例下的lib就有]:
- taglibs-standard-impl-1.2.5.jar
- taglibs-standard-spec-1.2.5.jar
(2)配置引入标签库taglib
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
(3) 使用jstl:
<% pageContext.setAttribute("myDate", new java.util.Date()); %>
北京时间: <fmt:formatDate value="${myDate}" pattern="yyyy=MM-dd HH:mm:ss"/>
3、后台往前台响应JSON时---Date类型
(1)方法1:在springmvc框架配置中添加json类型转化相关的配置[配置全局解析器]:
<!-- MVC注解解析器 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
(2)方式2:使用注解@JsonFormat
@Data
public class User {
private Long id;
private String username;
private Integer age;
//@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date hireDate;
}
★ 注意:@DateTimeFormat
是前台往后台传参【前台String类型-》后台Date类型】
★ 注意: 是后台响应给前台,响应为json格式(对时间Date类型的处理)
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!
学习SpringMVC必知必会(3)~springmvc的请求和响应的更多相关文章
- [ 学习路线 ] 2015 前端(JS)工程师必知必会 (2)
http://segmentfault.com/a/1190000002678515?utm_source=Weibo&utm_medium=shareLink&utm_campaig ...
- 《SQL必知必会》学习笔记二)
<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...
- 学习《SQL必知必会(第4版)》中文PDF+英文PDF+代码++福达BenForta(作者)
不管是数据分析还是Web程序开发,都会接触到数据库,SQL语法简洁,使用方式灵活,功能强大,已经成为当今程序员不可或缺的技能. 推荐学习<SQL必知必会(第4版)>,内容丰富,文字简洁明快 ...
- 《MySQL必知必会》学习笔记——前言
前言 MySQL已经成为世界上最受欢迎的数据库管理系统之一.无论是用在小型开发项目上,还是用来构建那些声名显赫的网站,MySQL都证明了自己是个稳定.可靠.快速.可信的系统,足以胜任任何数据存储业务的 ...
- 《SQL必知必会》学习笔记整理
简介 本笔记目前已包含 <SQL必知必会>中的所有章节. 我在整理笔记时所考虑的是:在笔记记完后,当我需要查找某个知识点时,不需要到书中去找,只需查看笔记即可找到相关知识点.因此在整理笔记 ...
- 《SQL必知必会》学习笔记(一)
这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...
- mysql学习--mysql必知必会1
例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式 ...
- mysql学习--mysql必知必会
上图为数据库操作分类: 下面的操作參考(mysql必知必会) 创建数据库 运行脚本建表: mysql> create database mytest; Query OK, 1 row ...
- 数据库学习之中的一个: 在 Oracle sql developer上执行SQL必知必会脚本
1 首先在開始菜单中打开sql developer: 2. 创建数据库连接 点击左上角的加号 在弹出的对话框中填写username和password 測试假设成功则点击连接,记得角色要写SYSDBA ...
- SQL必知必会,带你系统学习
你一定听说过大名鼎鼎的Oracle.MySQL.MongoDB等,这些数据库都是基于一个语言标准发展起来的,那就是SQL. SQL可以帮我们在日常工作中处理各种数据,如果你是程序员.产品经理或者是运营 ...
随机推荐
- Solution -「POJ 3710」Christmas Game
\(\mathcal{Decription}\) Link. 定义一棵圣诞树: 是仙人掌. 不存在两个同一环上的点,度数均 \(\ge 3\). 给出 \(n\) 棵互不相关的圣诞树,双人 ...
- 编译安装 tree 命令
文章目录 下载源码包 编译源码包 tree下载地址:http://mama.indstate.edu/users/ice/tree/ Centos发行版,可以直接使用命令 yum -y install ...
- 天啦,从Mongo到ClickHouse我到底经历了什么?
前言: 在实现前端监控系统的最初,使用了 Mongo 作为日志数据存储库.文档型存储,在日志字段扩展和收缩上都能非常方便.天生的 JSON 格式和 NodeJs 配合也非常贴合.就这样度过了几个月的蜜 ...
- OpenHarmony移植:如何适配utils子系统之KV存储部件
摘要:本文介绍移植开发板时如何适配utils子系统之KV存储部件,并介绍相关的运行机制原理. 本文分享自华为云社区<OpenHarmony移植案例与原理 - utils子系统之KV存储部件> ...
- 5款开源BI系统倾力推荐,企业信息化的利器
如今的企业都在选择开源BI系统,提升企业信息化的水平.那么开源BI系统到底该如何选择?在目前的百度上面有着许许多多类似的内容,本文就整理了其中优秀的5款工具,帮助大家选择合适的软件. 1.Smartb ...
- 用这个BI工具,不会代码的业务人员也能做数据分析!
随着企业的迅速发展,企业对数据分析的需求也在不断地凸显,但我们在实际的工作中经常会遇到这样尴尬的情形:擅长数据分析的人不懂业务,擅长业务的人又不了解数据分析.那么怎么让更懂业务逻辑.业务分析需求和痛点 ...
- python运算符优先级及部分运算
在python里面,有很多运算符,比如:算术运算符.赋值运算符.比较运算符.逻辑运算符.成员运算符.身份运算符和位运算符等.这里主要来看看这些运算符的优先级:从上到下优先级依次递减. 优先顺序 运算符 ...
- 【windows 访问控制】十二、C#实操 主体 System.Security.Principal 案例
案例1.主体(包含用户和组)和标识(用户名)的使用. PrincipalPolicy枚举:主体类型 分为window主体.未认证的主体和未分配主体GenericPrincipal.GenericIde ...
- PyTorch 中 torch.matmul() 函数的文档详解
官方文档 torch.matmul() 函数几乎可以用于所有矩阵/向量相乘的情况,其乘法规则视参与乘法的两个张量的维度而定. 关于 PyTorch 中的其他乘法函数可以看这篇博文,有助于下面各种乘法的 ...
- 痞子衡嵌入式:揭秘i.MXRTxxx系列上串行NOR Flash双程序可交替启动设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT500/600上串行NOR Flash双程序可交替启动设计. 在上一篇文章 <i.MXRT1170上串行NOR Fla ...