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.price
            where id = book.id;
         */
        System.out.println(m1 == m2);
        return "success";
    }

    @ModelAttribute
    public 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(隐式模型)
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44486437/article/details/113831179