SpringMVC study notes -03 receiving parameters

1. Parameter reception

        In servlet, we use HttpServletRequest, HttpServletResponse, HttpSession, SpringMVC also supports these three methods, and SpringMVC also has its own way of receiving processor requests:

A. Receive one by one

The formal parameter name of the handler method is required to be consistent with the parameter name in the request, and the parameters with the same name are assigned.

    <form action="test/receiveProperty.do" method="post">
        姓名:<input type="text" name="name"><br>
        年龄:<input type="text" name="age"><br>
        <input type="submit" value="提交参数">
    </form>
    @RequestMapping(value = "/receiveProperty.do")
    public ModelAndView doReceiveProperty(String name,int age){
        ModelAndView modelAndView = new ModelAndView();

        modelAndView.addObject("name",name);
        modelAndView.addObject("age",age);

        modelAndView.setViewName("showProperty");

        return modelAndView;
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <p>name:${requestScope.get("name")}</p>
    <p>age:${requestScope.get("age")}</p>
</body>
</html>

1. The parameter assignment process of SpringMVC:

    1. Use the getParameter method of the request object to receive the requested parameters

    2. Call the processor method corresponding to the request path through DispatcherServlet, and assign the value according to the parameter name (it can automatically complete the type conversion for us)

2. Question 1 :

    Because of age we use the int type parameter to receive, if we pass the parameter, the age field is not assigned, then the passed in is an empty string, and the type conversion cannot be completed.

    The same is true for floating-point numbers, because this is a type conversion from string to int, not a forced type conversion from float to int. Strings like "21.6" cannot be parsed as int normally.

Processor error -400: Client error, indicating that an error occurred during the submission of the request parameters.

Solution-1: We use wrapper classes instead of basic types. When the value cannot be assigned, the parameter value can be null

    @RequestMapping(value = "/receiveProperty.do")
    public ModelAndView doReceiveProperty(String name,Integer age){
        ModelAndView modelAndView = new ModelAndView();

        System.out.println("age = " + age);
        
        modelAndView.addObject("name",name);
        modelAndView.addObject("age",age);

        modelAndView.setViewName("showProperty");

        return modelAndView;
    }

This method can only receive empty input, but for floating-point or string data that will cause an error in the String to int conversion, there is no way to receive it.

Solution-2: Since the transmitted data is all String, we can all use String to accept

This method can accept any type of input, but after we receive it, we still have to do the type conversion manually. When we find that the conversion is not possible, he should not be allowed to execute it, and the framework also refuses to execute it when the input is illegal. In one fell swoop. It is equivalent to the framework automatically helps us isolate illegal input.

3. Question 2:

Post request cannot pass Chinese characters correctly:

But Get can:

In Servlet, we can solve by setting the requested character encoding:

public void doPost(HttpServletRequest request){
    request.setCharacterEncoding("utf-8");
}

SpringMVC provides a filter to help us solve the problem of garbled characters: we can define it ourselves, or use the CharacterEncodingFilter provided by the framework, we need to configure it in 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>
        <!--强制request使用设定的编码-->
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--强制response使用设定的编码-->
        <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>

As we said before, SpringMVC actually takes and puts parameters, but actually uses request and response, so we only need to specify the encoding of the request and response objects.

In fact, the principle of the filter is to execute the following code:

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        if (encoding != null) {
            if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                request.setCharacterEncoding(encoding);
            }

            if (this.isForceResponseEncoding()) {
                response.setCharacterEncoding(encoding);
            }
        }

        filterChain.doFilter(request, response);
    }

In fact, it uses setCharacterEncoding of request and response objects. The power of the filter is that the encoding method can be set for all matching requests without manually setting it in the processor method.

4. The passed parameter name and the received parameter name are inconsistent

       Sometimes we can't modify the names of these two parameters to be consistent. SpringMVC provides @RequestParam to let us specify which parameter passed over should be assigned to which parameter is responsible for receiving.

    <p>提交参数</p>
    <form action="test/receiveProperty.do" method="post">
        姓名:<input type="text" name="rname"><br>
        年龄:<input type="text" name="rage"><br>
        <input type="submit" value="提交参数">
    </form>
    @RequestMapping(value = "/receiveProperty.do")
    public ModelAndView doReceiveProperty(@RequestParam(value = "rname") String name,@RequestParam(value = "rage") Integer age){
        ModelAndView modelAndView = new ModelAndView();

        System.out.println("age = " + age);

        modelAndView.addObject("name",name);
        modelAndView.addObject("age",age);

        modelAndView.setViewName("showProperty");

        return modelAndView;
    }

B. Received by the subject

        When there are too many parameters, it is very cumbersome to receive the parameters one by one. SpringMVC also provides a way to receive by object. Based on the experience of receiving one by one above, it is not difficult to guess that this requires the attribute name in the object and the requested parameter name Consistent.

    <p>提交对象</p>
    <form action="test/receiveObjct.do" method="post">
        姓名:<input type="text" name="name"><br>
        年龄:<input type="text" name="age"><br>
        <input type="submit" value="提交参数">
    </form>
package com.zzt.Vo;

public class Student {
    private String name;
    private Integer age;

    public Student() {
        System.out.println("----无参构造----");
    }

    public Student(String name, Integer age) {
        System.out.println("----有参构造----");
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("----setName----" + name);
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        System.out.println("----setAge----" + age);
        this.age = age;
    }
}
    @RequestMapping(value = "/receiveObjct.do")
    public ModelAndView doReceiveObject(Student student){
        ModelAndView modelAndView = new ModelAndView();

        modelAndView.addObject("name",student.getName());
        modelAndView.addObject("age",student.getAge());

        modelAndView.setViewName("showProperty");

        return modelAndView;
    }

        As shown in the figure above, SpringMVC first uses a parameterless construction method to create an entity class object. This process is executed when we submit a request and the request reaches the corresponding processor method (the formal parameter of the processor method is an object), and then the framework The property will be injected by calling the setter.

       It is worth noting that this method must require the class attribute name to be consistent with the request parameter name, otherwise it cannot be assigned normally, because the framework knows the attribute name of the request parameter to be injected through the setter, and then finds the corresponding request parameter for injection, so If the names are inconsistent, no parameters are found at all, and there is no way to talk about injection. In addition, the scope of @RequestParam is limited to method parameters: @Target({ElementType.PARAMETER}).

2.SpringMVC的MVC

      SpringMVC corresponds to the V-interface layer in the three-tier architecture, which is used to receive user requests and return processing results. But SpringMVC is called SpringMVC because the framework itself is also built in accordance with the MVC pattern, Front controller (front-end controller, central dispatcher DispatcherServlet), Controller (back-end controller), Model (model, used to store data), View (view, used to display data). In the development of the entire SSM project, it still lacks the Spring management business layer and Mybatis management persistence layer.

Guess you like

Origin blog.csdn.net/qq_39304630/article/details/112916676