【SpringMVC】三、SpringMVC获取请求参数与域数据共享

SpringMVC获取请求参数

ServletAPI

使用ServletAPI获取参数,Servlet是由DispatcherServlet来匹配前端的请求URL和@RequestMapping的value值,并且DispatcherServlet还会封装一系列的参数,再通过注入的方式给参数赋值。

前端:

    <a th:href="@{/testServletAPI(username='admin', password=123456)}">测试使用servletAPI获取请求参数a>

后端:

    @RequestMapping( value = "/testServletAPI")
    public String testServletAPI (HttpServletRequest request) {
        //获取参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username: " + username + ", password: " + password);
        return "success";
    }
}

通过传入HttpServletRequest参数来从网页传入的请求中获取参数,

一般不使用这种方式进行参数获取,SpringMVC提供了更为强大的接口来获取参数。

控制器形参的方式获取请求参数

通过前端传参的参数名与控制器方法的形参一致的条件来获取参数。

后端:

    @RequestMapping (value = "/testParam")
    //注意复选框可以直接使用String传入,也可以使用String[]数组传入
    //若是由String传入的,则多个数据会以逗号为分割拼接成一个字符串
    public String testParam(String username, String password, String[] hobby) {
        System.out.println("username: " + username + ", password: " + password + ", hobby: " + Arrays.toString(hobby));
        return "success";
    }

前端:

    <form th:action="@{/testParam}" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        爱好:<input type="checkbox" name="hobby" value="a">a
             <input type="checkbox" name="hobby" value="b">b
             <input type="checkbox" name="hobby" value="c">c<br>
        <input type="submit" value="使用控制器获取请求参数">
    form>

特别的,使用@RequestParam进行传入请求参数的配置:

//@RequestParam注解将前端的name与后端的形参形成映射,使其就算名称不同也可以对应起来
//Required参数是是否必须手动设置初值
//default参数设置默认值,当没有传参时传入默认值
public String testParam(@RequestParam(value = "user_name", required = false, defaultValue = "我是默认值")String username,
                        String password,
                        String[] hobby) {
    System.out.println("username: " + username + ", password: " + password + ", hobby: " + Arrays.toString(hobby));
    return "success";

同样的,还有将请求头信息和形参对应的注解@RequestHeader以及将Cookie和形参对应的注解@CookieValue,使用方法与@RequestParam相同。

例如:

    public String testParam(
        @RequestParam(value = "user_name", required = false, defaultValue = "我是默认值")String username,
                            String password,
                            String[] hobby,
                            @RequestHeader(value = "Host")String host) {
        System.out.println("username: " + username + ", password: " + password + ", hobby: " + Arrays.toString(hobby));
        System.out.println("Host: " + host);
        return "success";
    }

但注意@RequestHeader不能像@RequestParam一样通过相同的形参名称来省略注解,其必须使用注解。

session是服务器端的会话技术、Cookie是客户端的会话技术

每当创建一个session时、就会同时创建一个cookie(例如在Controller中使用request.getsession()方法来创建一个session,session在创建的同时就会创建一个cookie,该Cookie会存储在Response中,其存储形式为:(Set-Cookie:(JSESSIONID-一段随机序列号))

而在第一次创建之后,Cookie就不会存储在响应报文中了,而会存储在请求报文中(仍旧以键值对的形式)

    public String testParam(
        					@RequestParam(value = "user_name", required = false, defaultValue = "我是默认值")String username,
                            String password,
                            String[] hobby,
                            @RequestHeader(value = "Host")String host,
                            @CookieValue(value = "JSESSIONID")String JSESSIONID) {
        System.out.println("username: " + username + ", password: " + password + ", hobby: " + Arrays.toString(hobby));
        System.out.println("Host: " + host);
        System.out.println("JSESSIONID: " + JSESSIONID);
        return "success";
    }

通过POJO直接获取参数(将前端的数据直接传给后端的实体类对象)

将前端传入的数据直接传入后端的JavaBean中,将其注入到一个实体类对象的属性中,注意前端的name属性必须与后端javaBean对象的属性名一致

    <form th:action="@{/testPOJO}" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        性别:<input type="radio" name="sex" value=""><input type="radio" name="sex" value=""><br>
        年龄:<input type="text" name="age"><br>
        邮箱:<input type="text" name="email"><br>
        <input type="submit" value="使用POJO接收实体类对象">
    form>

javaBean:(注意必须生成有参和无参构造,生成getset方法)

    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;

Controller:

    @RequestMapping ("/testPOJO")
    public String testPOJO (User user) {
        System.out.println(user);
        return "success";
    }

乱码问题

get请求出现乱码是由tomcat造成的,在70行左右的connector标签中加入 URIEncoding="UTF-8"就可以解决tomcat引起的get请求的乱码问题。

而post请求的乱码问题,使用SpringMVC提供的编码过滤器进行设置编码

在web.xml中注册filter,/*表示所有都生效

    <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>forceResponseEncodingparam-name>  
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

域对象共享数据

当我们需要将数据传给前台页面的时候,我们就需要将数据传给域对象,再由域对象进行共享。

request -> 一次请求

Session -> 浏览器开启 - 浏览器关闭

ServletContext -> 服务器开启 - 服务器关闭

Session的钝化:Session会将浏览器中的数据经过序列化之后存储到磁盘中,而当浏览器没有关闭,而是重新请求时,session会经过活化将数据再显示在浏览器中。

只要Cookie存在,则Session一直都是只存在一个

使用ServletAPI向域对象共享数据

利用request.setAttribute(“键”,“值”)的方式进行数据共享

后端:

    @RequestMapping( value = "/testRequestByServletAPI")
    public String testRequestByServletAPI (HttpServletRequest request) {
        //使用servletAPI获取数据,将键值对存入request作用域
        request.setAttribute("testRequestScope", "hello, ServletAPI");
        return "success";
    }

前端:

success<br>


<p th:text="${testRequestScope}">p>

使用ModelAndView向Request域中共享数据

ModelAndView要求返回一个ModelAndView对象,使用.addAttribute(“键”,“值”)的方式添加数据,使用.setViewName()的方式设置视图名称。

    @RequestMapping ( value = "/testModelAndView" )
    public ModelAndView testModelAndView () {
        //创建ModelAndView对象
        ModelAndView mav = new ModelAndView();

        //调用对应方法向request作用域中添加数据
        //两个参数,前一个是键,后一个是值
        mav.addObject("testRequestScope", "Hello,ModelAndView");

        //设置视图名称
        mav.setViewName( "success" );

        return mav;
    }

使用Model向Request域中共享数据

在形参位置传入一个Model,使用model.addAttribute(“键”,“值”)的方式来向域对象中添加数据,但视图名称还是使用return的方式进行设置。

    @RequestMapping (value = "/testModel")
    public String testModel (Model model) {
        model.addAttribute("testRequestScope", "Hello, Model");
        return "success";
    }

使用Map向Request域中共享数据

在形参位置传入一个Map形参,MVC会将该map中所有的键值对都添加到Request作用域中。

    @RequestMapping (value = "/testMap")
    public String testMap (Map<String, Object> map) {
        map.put("testRequestScope", "Hello, map");
        return "success";
    }

使用ModelMap向Request域中共享数据

在形参位置传入一个ModelMap,使用modelMap.addAttribute(“键”,“值”)的方法向Request域对象中共享数据。

    @RequestMapping (value = "/testModelMap")
    public String testModelMap (ModelMap modelMap) {
        modelMap.addAttribute("testRequestScope", "Hello, ModelMap");
        return "success";
    }

其中,Model、Map、ModelMap都是由BindingAwareModelMap实现的,其类型都一致。

向session共享数据

使用最基础的通过servleyAPI的方式向Session中共享数据

注意形参中传入HttpSession,使用session.setAttribute(“键”,“值”);的方法进行注入。

    @RequestMapping (value = "/testSession")
    public String testSession (HttpSession session) {
        session.setAttribute("testSessionScope", "Hello Session");
        return "success";
    }

注意在前端中,使用session作用域的对象需要在前面加上session.

<p th:text="${session.testSessionScope}">p>

向Application中共享数据(一般没有)

使用最基础的通过servleyAPI的方式向Applicationn中共享数据

形参中传入HttpSession,使用session.getServletContext获取Application对象,再通过Application对象中的setAttribute方法为对象赋值。

    @RequestMapping (value = "/testApplication")
    public String testApplication(HttpSession session) {
        //ServletContext是由服务器在初始化的时候创建的,所以存储在ServletContext中的数据在服务器的一整个过程中都存在
        ServletContext application = session.getServletContext();
        application.setAttribute("testApplicationScope", "Hello ServletContext");
        return "success";
    }

你可能感兴趣的:(SpringMVC,servlet,java,前端)