▷ Controller方法该怎么返回、Controller数据该怎么进行共享
//返回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(); }
常用
】返回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; }
常用
】返回String类型(是逻辑视图名称
),参数是Model类型(是共享数据
) //返回string,逻辑视图名称,此时需要结合参数Model类型 一起使用 @RequestMapping("/test4") public String test4(Model model) {
//设置共享数据 model.addAttribute("叩丁狼"); model.addAttribute("msg", "教育"); return "welcome";//设置跳转的视图 }
//请求转发,浏览器地址栏不变,可以共享请求中的数据 //原理:request.getRequestDispatcher("").forward(request, response); @RequestMapping("/test5") public String test5(Model model) {
return "forward:/hello.jsp";//设置跳转的视图 }
//重定向,浏览器地址栏改变,不能共享请求中的数据 //原理:request.sendRedirect(""); @RequestMapping("/test6") public String test6(Model model) {
return "redirect:/hello.jsp";//设置跳转的视图 }
访问资源的时候,都使用/开头
]根路径
开始去寻找资源上一级上下文路径
中去寻找资源
请求转发/URL重定向 | 请求转发 | URL重定向 |
---|---|---|
地址栏改变? | 不会 | 会改变 |
共享数据? | 可以 | 不可以? |
表单重复提交? | 会发生 | 不会发生 |
只能是从Controller 重定向到 Controller,不能到jsp
//重定向:从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; }
接收请求参数的处理
)
@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); } }
▷ 因为Controller(Servlet) 是单例的,线程不安全,一般不用成员变量,
除非要共享的数据,才作为成员变量。
//获取请求参数:通过保证请求参数名称和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); }
编码过滤器
: <!-- (针对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>
//restfull风格传递参数 //PathVariable: 可以将url中占位符绑定到方法的形参中 @RequestMapping("/r/{id}") public ModelAndView rest(@PathVariable("id") Integer id) {
System.out.println("id:" + id); return null; }
//接收一个参数有很多值的情况 //使用数组:可以直接接收 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()); }
将请求参数封装成一个对象
】 //封装成一个对象 @RequestMapping("/bean") //batchDelete?ids=10&ids=20&ids=30 public void bean(User user) {
System.out.println(user); }
直接把请求参数封装成javaBean对象
数组
接收多个参数给共享的model数据设置key名,贴在形参上,也可以贴在方法上,
针对复合类型参数,缺省情况下就会放到model中(共享), 缺省的key就是类型首字母小写
//ModelAttribute注解: /* *1、给共享的model数据设置key名,贴在形参上,也可以贴在方法上 * 针对复合类型(非简单类型)参数,缺省情况下就会放到model中(共享), 缺省的key就是类型首字母小写 * 2、可以标注一个非请求处理的方法,被标注的方法,每次在请求处理方法之前都会优先被执行[存放多个请求需要共享的数据] */ @RequestMapping("/test11") public String test1(@ModelAttribute("u") User user) {
System.out.println(user); return "welcome"; }
@RequestHeader
@RequestMapping("/test1") public ModelAndView test1(@RequestHeader("User-Agent") String userAgent) {
System.out.println("test1"); System.out.println("User-Agent:" + userAgent); return null; }
@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; }
@SessionAttributes
@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
/* * 需要吧表单数据封装到多个对象中去,若各个对象有相同的属性时 * 不知道该把哪一个参数封装到哪一个对象 */ @RequestMapping("/save") public ModelAndView save(Cat cat, Dog dog) {
System.out.println("提交数据"); System.out.println(cat); System.out.println(dog); return null; }
<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>
解决:
<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>
//从参数--> 对象,封装规则需要我们来设置 //自定义数据绑定注册,将请求参数转化成对应对象的属性 @InitBinder("cat") public void initBinderCat(WebDataBinder binder) {
//设置字段以什么做为前缀 binder.setFieldDefaultPrefix("cat."); } @InitBinder("dog") public void initBinderDog(WebDataBinder binder) {
//设置字段以什么做为前缀 binder.setFieldDefaultPrefix("dog."); }
@ResponseBody
@RestController
@RequestBody
//把单个对象/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, 你好~"; }
//从前台---->后台传递参数 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)); } }
(1)导入jar包[tomcat服务器examples案例下的lib就有]:
(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"/>
(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>
@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类型的处理)
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!