SpringMVC-请求处理与数据输出

请求处理

三种注解

RequestParam 获取请求参数

 /*** 默认情况下函数参数就是需要获取的字段值,若不传值则为null* 当请求信息里面的字段与需要获取的字段名称不一样时,则可使用@RequestParam("user")注解来获取值,这种情况下* 必须传递值,否则报错* RequestParam注解属性* * value:指定获取的参数key* * required 是否必须传值,默认是true* * defaultValue:默认值* 注意区分:** @RequestParam("user")* @PathVariable("user") /book/{user}?user=zhangsan*/@RequestMapping("/handle01")public String handle01(@RequestParam("user") String username) {System.out.println(username);return "success";}

RequestHeader 获取请求头参数

/*** RequestHeader:获取请求头的信息* 用法与RequestParam类似* 该注解的属性* * value:指定获取的参数key* * required 是否必须传值,默认是true* * defaultValue:默认值*/@RequestMapping("/handle02")public String handle02(@RequestHeader("User-Agent") String userAgent) {System.out.println(userAgent);return "success";}

CookieValue 获取某个cookie的值

/*** @CookieValue:获取cookie的值 用法与RequestParam类似* 该注解的属性* * value:指定获取的参数key* * required 是否必须传值,默认是true* * defaultValue:默认值*/@RequestMapping("/handle03")public String handle03(@CookieValue("JSESSIONID") String JSESSIONID) {System.out.println(JSESSIONID);return "success";}

POJO (Plain old Java Object) 自动封装

可以直接将请求的参数封装为POJO类
前端代码

<form action="addBook" method="post">书名 <input type="text" name="bookName">作者 <input type="text" name="author">价格 <input type="text" name="prices">库存 <input type="text" name="stock">销量 <input type="text" name="sales">省份 <input type="text" name="address.province">城市 <input type="text" name="address.city">街道 <input type="text" name="address.street"><input type="submit">
</form>

后端代码

    /*** 如果我们请求的参数是一个POJO* 则SpringMVC则会自动进行赋值* 将POJO中的每个属性,从request尝试出来,并封装(当属性名相同时才可以进行封装)* 还可以级联封装** @param book* @return*/@RequestMapping("/addBook")public String addBook(Book book) {System.out.println(book);return "success";}

支持原生API

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale:国际化有关的区域信息
  • InputStream //字节流1
  • OutputStream
  • Reader //字符流
  • Writer

乱码问题解决

  • get请求
    修改server.xml配置
    <Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />
  • post请求
    • 请求乱码
      request.setCharacterEncoding(“UTF-8”)
      可以使用 org.springframework.web.filter.CharacterEncodingFilter 在web.xml文件中进行配置,要在其他filter之前
    <!--字符编码--><!--要在其他filter之间--><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>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
  • 响应乱码
    response.setContentType(“text/html;charset=utf-8”)

数据输出

使用原生API

使用Map、Model或ModelMap作为函数参数

Map

直接存储值就可以

    @RequestMapping("/demo01")public String demo01(Map<Stringa, Object> map) {System.out.println(map.getClass());map.put("msg", "你好");return "success";}

Model

    @RequestMapping("/demo02")public String demo02(Model model) {model.addAttribute("msg", "hahah");System.out.println(model.getClass());return "success";}

ModelMap

    @RequestMapping("/demo03")public String demo03(ModelMap model) {model.addAttribute("msg", "呵呵呵");System.out.println(model.getClass());return "success";}

总结

  • 真正执行他们的类均是class org.springframework.validation.support.BindingAwareModelMap
  • 所存储的数据均存在于request域中
  • 通过比较,对于以上三个方法中的BindingAwareModelMap对象不是同一个

ModelAndView

顾名思义:既包含视图数据,也包含模型数据

    @RequestMapping("/demo04")public ModelAndView demo04() {
//        构造参数是要跳转的页面
//        ModelAndView modelAndView = new ModelAndView("success");ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("success");modelAndView.addObject("msg", "你好!");return modelAndView;}

SessionAttributes注解

给BindingAwareModelMap或ModelAndView中保存的数据,同时也session保存一份

  • value属性:指定要保存至session的数值对应的在request域中的key
  • type属性:指定要保存至session的数值对应的在request域中value的类型

ModelAttributeTest注解详解

业务场景引入

以修改图书信息为例,一般图书名称是不需要修改的,但是当修改信息时,传入的图书名称是null,从而在dao层会出现异常
因此可以使用ModelAttribute注解来解决

注解思路

package pers.lele.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import pers.lele.domain.Book;import java.util.Map;@Controller
@RequestMapping("/book")
public class BookControl {Object m1;Object m2;Object m3;Object b1;Object b2;boolean flag = false;@RequestMapping("/update")public String updateBook(@ModelAttribute("book") Book book, ModelMap map) {System.out.println(book);b2 = book;System.out.println(b1 == b2);//SpringMVC创建一个Book对象,值默认都是null//Book{id='100', name='null', price=12.0, sell=12}m2 = map;System.out.println(m2);/*upadte book set name = book.name , price = book.pricewhere id = book.id;*/System.out.println(m1 == m2);return "success";}@ModelAttributepublic void udpateBefore(Model model) {if (flag == false) {Book book = new Book("100", "水浒传", 12, 65);b1 = book;model.addAttribute("book", book);System.out.println("udpateBefore....");m1 = model;System.out.println(m1);flag = true;}}@RequestMapping("/updateplus")public String updateplus(@ModelAttribute("name") String name,ModelMap map) {map.addAttribute("haha","haha");System.out.println(map.get("book"));m3 = map;System.out.println("updateplus");System.out.println(m1);System.out.println(m2);System.out.println(m3);System.out.println(m1 == m2);System.out.println(m1 == m3);return "success";}
}

总结

被@ModelAttribute注解标志的方法会优先被执行且使用的是同一个 BindingAwareModelMap(隐式模型)

SpringMVC-请求处理与数据输出

请求处理

三种注解

RequestParam 获取请求参数

 /*** 默认情况下函数参数就是需要获取的字段值,若不传值则为null* 当请求信息里面的字段与需要获取的字段名称不一样时,则可使用@RequestParam("user")注解来获取值,这种情况下* 必须传递值,否则报错* RequestParam注解属性* * value:指定获取的参数key* * required 是否必须传值,默认是true* * defaultValue:默认值* 注意区分:** @RequestParam("user")* @PathVariable("user") /book/{user}?user=zhangsan*/@RequestMapping("/handle01")public String handle01(@RequestParam("user") String username) {System.out.println(username);return "success";}

RequestHeader 获取请求头参数

/*** RequestHeader:获取请求头的信息* 用法与RequestParam类似* 该注解的属性* * value:指定获取的参数key* * required 是否必须传值,默认是true* * defaultValue:默认值*/@RequestMapping("/handle02")public String handle02(@RequestHeader("User-Agent") String userAgent) {System.out.println(userAgent);return "success";}

CookieValue 获取某个cookie的值

/*** @CookieValue:获取cookie的值 用法与RequestParam类似* 该注解的属性* * value:指定获取的参数key* * required 是否必须传值,默认是true* * defaultValue:默认值*/@RequestMapping("/handle03")public String handle03(@CookieValue("JSESSIONID") String JSESSIONID) {System.out.println(JSESSIONID);return "success";}

POJO (Plain old Java Object) 自动封装

可以直接将请求的参数封装为POJO类
前端代码

<form action="addBook" method="post">书名 <input type="text" name="bookName">作者 <input type="text" name="author">价格 <input type="text" name="prices">库存 <input type="text" name="stock">销量 <input type="text" name="sales">省份 <input type="text" name="address.province">城市 <input type="text" name="address.city">街道 <input type="text" name="address.street"><input type="submit">
</form>

后端代码

    /*** 如果我们请求的参数是一个POJO* 则SpringMVC则会自动进行赋值* 将POJO中的每个属性,从request尝试出来,并封装(当属性名相同时才可以进行封装)* 还可以级联封装** @param book* @return*/@RequestMapping("/addBook")public String addBook(Book book) {System.out.println(book);return "success";}

支持原生API

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale:国际化有关的区域信息
  • InputStream //字节流1
  • OutputStream
  • Reader //字符流
  • Writer

乱码问题解决

  • get请求
    修改server.xml配置
    <Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />
  • post请求
    • 请求乱码
      request.setCharacterEncoding(“UTF-8”)
      可以使用 org.springframework.web.filter.CharacterEncodingFilter 在web.xml文件中进行配置,要在其他filter之前
    <!--字符编码--><!--要在其他filter之间--><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>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
  • 响应乱码
    response.setContentType(“text/html;charset=utf-8”)

数据输出

使用原生API

使用Map、Model或ModelMap作为函数参数

Map

直接存储值就可以

    @RequestMapping("/demo01")public String demo01(Map<Stringa, Object> map) {System.out.println(map.getClass());map.put("msg", "你好");return "success";}

Model

    @RequestMapping("/demo02")public String demo02(Model model) {model.addAttribute("msg", "hahah");System.out.println(model.getClass());return "success";}

ModelMap

    @RequestMapping("/demo03")public String demo03(ModelMap model) {model.addAttribute("msg", "呵呵呵");System.out.println(model.getClass());return "success";}

总结

  • 真正执行他们的类均是class org.springframework.validation.support.BindingAwareModelMap
  • 所存储的数据均存在于request域中
  • 通过比较,对于以上三个方法中的BindingAwareModelMap对象不是同一个

ModelAndView

顾名思义:既包含视图数据,也包含模型数据

    @RequestMapping("/demo04")public ModelAndView demo04() {
//        构造参数是要跳转的页面
//        ModelAndView modelAndView = new ModelAndView("success");ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("success");modelAndView.addObject("msg", "你好!");return modelAndView;}

SessionAttributes注解

给BindingAwareModelMap或ModelAndView中保存的数据,同时也session保存一份

  • value属性:指定要保存至session的数值对应的在request域中的key
  • type属性:指定要保存至session的数值对应的在request域中value的类型

ModelAttributeTest注解详解

业务场景引入

以修改图书信息为例,一般图书名称是不需要修改的,但是当修改信息时,传入的图书名称是null,从而在dao层会出现异常
因此可以使用ModelAttribute注解来解决

注解思路

package pers.lele.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import pers.lele.domain.Book;import java.util.Map;@Controller
@RequestMapping("/book")
public class BookControl {Object m1;Object m2;Object m3;Object b1;Object b2;boolean flag = false;@RequestMapping("/update")public String updateBook(@ModelAttribute("book") Book book, ModelMap map) {System.out.println(book);b2 = book;System.out.println(b1 == b2);//SpringMVC创建一个Book对象,值默认都是null//Book{id='100', name='null', price=12.0, sell=12}m2 = map;System.out.println(m2);/*upadte book set name = book.name , price = book.pricewhere id = book.id;*/System.out.println(m1 == m2);return "success";}@ModelAttributepublic void udpateBefore(Model model) {if (flag == false) {Book book = new Book("100", "水浒传", 12, 65);b1 = book;model.addAttribute("book", book);System.out.println("udpateBefore....");m1 = model;System.out.println(m1);flag = true;}}@RequestMapping("/updateplus")public String updateplus(@ModelAttribute("name") String name,ModelMap map) {map.addAttribute("haha","haha");System.out.println(map.get("book"));m3 = map;System.out.println("updateplus");System.out.println(m1);System.out.println(m2);System.out.println(m3);System.out.println(m1 == m2);System.out.println(m1 == m3);return "success";}
}

总结

被@ModelAttribute注解标志的方法会优先被执行且使用的是同一个 BindingAwareModelMap(隐式模型)