Spring MVC Series Part 4: how many ways to accept parameters?

Posted by fydwell on Fri, 12 Nov 2021 23:09:32 +0100

1. Content of this article

How do the methods in the Controller receive parameters from http requests?

What are the specific ways?

These are the focus of this paper. This paper mainly introduces the reception of parameters in the following ways

  • Receive parameters in the Servlet: HttpServletRequest, HttpServletResponse, HttpSession

  • Receive parameters by method parameter name

  • Receive parameters through @ RequestParam

  • Receive parameters through 1 object

  • Receive parameters through multiple objects

  • Composite objects receive parameters (nested object sets in objects, etc.)

  • Accept parameters in url through @ PathVariable

2. Receive parameters in Servlet

For example, if we want to use the objects in the servlet in the method: HttpServletRequest, HttpServletResponse and HttpSession, we can directly declare these objects in the method parameters. Spring MVC will automatically pass in these parameters and declare which one is used

@RequestMapping("/receiveparam/test1.do")
public ModelAndView test1(HttpServletRequest request,
                          HttpServletResponse response,
                          HttpSession session) {
    String name = request.getParameter("name");
    String age = request.getParameter("age");
    String msg = String.format("name:%s,age:%s", name, age);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

Corresponding form

<form method="post" action="receiveparam/test1.do">
    full name:<input name="name" value="Passerby"/> <br/>
    Age:<input name="age" value="30"/><br/>
    <input type="submit" value="Submit">
form>

3. Solve the problem of garbled code

If you directly create a spring MVC project and run the above case, you will find that when the name is Chinese, it will be garbled. Here, you need to add the following configuration in web.xml to solve the garbled problem

<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>forceRequestEncodingparam-name>
        <param-value>trueparam-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>

The above configuration mainly adds a filter, which will process all requests, which is equivalent to the following operations for all requests. For encoding, we set UTF-8

request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);

4. Receive parameters by method parameter name

form

<form method="post" action="receiveparam/test2.do">
    full name:<input name="name" value="Passerby"/> <br/>
    Age:<input name="age" value="30"/><br/>
    <input type="submit" value="Submit">
form>

Controller method

/**
 * springmvc Before calling this method, the parameter value will be obtained from the request according to the method parameter name and passed in
 * Process:
 * 1,Pass request.getParameter("name") to the first parameter name of the method
 * 2,Pass Integer.valueOf(request.getParameter("age") to the second parameter of the method, age
 *
 * @param name
 * @param age
 * @return
 */
@RequestMapping("/receiveparam/test2.do")
public ModelAndView test2(String name, Integer age) {
    String msg = String.format("name:%s,age:%s", name, age);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

In this case, the parameter name in the form is the same as the parameter name in the controller method, and will be assigned one by one according to the name.

5. Receive parameters through @ RequestParam

If the parameter name of the method is inconsistent with the parameter name in the form, you can specify the parameter name in the form through the value attribute of the @ RequestParam annotation.

For example, the two names of the following form are pname and page

<form method="post" action="receiveparam/test3.do">
    full name:<input name="pname" value="Passerby"/> <br/>
    Age:<input name="page" value="30"/><br/>
    <input type="submit" value="Submit">
form>

The corresponding methods are as follows. The parameter names of the two formal parameters are name and age respectively, which is inconsistent with the name in the form. Then you can add @ RequestParam annotation in front of the parameter of the method. The value of the annotation is the name of the element in the form. If the parameter name wants to accept the value of pname in the form, you need to add @ RequestParam("pname") in front of the parameter name, The second parameter of the method is the same, with @ RequestParam("page")

/**
 * If the parameter name of the method is inconsistent with the parameter name in the form, you can  @ The value attribute of the RequestParam annotation specifies the name of the parameter in the form
 * For example: @ RequestParam("pname")   String   name   receive   request.getParameter("pname")   Value of
 * 1,Pass request.getParameter("pname") to the first parameter name of the method
 * 2,Pass integer. Valueof (request. Getparameter ("p age") to the second parameter of the method
 *
 * @param name
 * @param age
 * @return
 */
@RequestMapping("/receiveparam/test3.do")
public ModelAndView test3(@RequestParam("pname") String name,
                          @RequestParam("page") Integer age) {
    String msg = String.format("name:%s,age:%s", name, age);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

@RequestParam is used to bind the parameters of the request and the parameters of the method. This annotation also has several properties, which are also commonly used. Let's get familiar with them

public @interface RequestParam {

 //Parameter name
 @AliasFor("name")
 String value() default "";

 //Same as value attribute
 @AliasFor("value")
 String name() default "";

 //Whether the parameter is required or not is set to true by default. If there is no parameter in the request, spring MVC will report an error
 boolean required() default true;

 //Default value
 String defaultValue() default ValueConstants.DEFAULT_NONE;

}

6. Receive parameters through 1 object

Generally, there should be no more than 5 methods. When there are many parameters in the http request, we can use an object to receive. The parameter name in the object is consistent with that in the http request.

For example, there are the following forms

<form method="post" action="receiveparam/test4.do">
    full name:"name" value="Passerby"/> 

    Age:"age" value="30"/>

    <input type="submit" value="Submit">

</input type=</form method=

We can define a UserInfoDto class to receive the parameters in the form. There are two attribute names in this class, which are the same as those in the form above.

public class UserInfoDto {
    //full name
    private String name;
    //Age
    private Integer age;

    //get and set methods are omitted

    @Override
    public String toString() {
        return "UserModel{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

The code of the corresponding controller is as follows

/**
 * Transfer object information. When there are many parameters, you can transfer information through objects
 * For example, there are two parameters (name, age) in the form
 * Then you can define a class userinfodto (two attributes: name and age)   To receive the parameters submitted by the form
 * The method parameters of the controller are: (UserInfoDto userInfoDto)
 * springmvc When this method is called, the UserModel will be created automatically, and the parameters in the request will be set to by name   UserInfoDto   And then pass it in
 * It is equivalent to executing the following code:
 * UserInfoDto user = new UserInfoDto();
 * user.setName(request.getParameter("name"));
 * user.setAge(Integer.valueOf(request.getParameter("age")));
 * Then pass the user object to the first parameter of the current method
 *
 * @param userInfoDto
 * @return
 */
@RequestMapping("/receiveparam/test4.do")
public ModelAndView test4(UserInfoDto userInfoDto) {
    String msg = String.format("userDto: %s", userInfoDto);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

7. Receive parameters through multiple objects

Above, we will show that the form has one object to receive, in fact, it can also be received with multiple objects.

The form is as follows

<form method="post" action="receiveparam/test5.do">
    full name:<input name="name" value="Passerby"/> <br/>
    Age:<input name="age" value="30"/><br/>

    Working years:<input name="workYears" value="10"/> <br/>
    Age:<input name="workAddress" value="Shanghai"/><br/>
    <input type="submit" value="Submit">
form>

There are four elements in the form. We use two objects to receive. The first two elements are received with UserInfoDto objects and the last two objects are received with WorkInfoDto objects. We need to define two classes: UserInfoDto and WorkInfoDto

/**
 * Basic user information
 */
public class UserInfoDto {
    //full name
    private String name;
    //Age
    private Integer age;

     //get and set methods are omitted

    @Override
    public String toString() {
        return "UserModel{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

/**
 * Basic work information
 */
public class WorkInfoDto {
    //Working years
    private Integer workYears;
    //Duty station
    private String workAddress;

 //get and set methods are omitted

    @Override
    public String toString() {
        return "WorkInfoDto{" +
                "workYears=" + workYears +
                ", workAddress='" + workAddress + '\'' +
                '}';
    }
}

The corresponding controller method is as follows

/**
 * It can also be received with multiple objects
 * For example, the form has four elements [name,age,workYear,workAddress]
 * Where requested parameters   name,age   Assigned to 2 attributes (name, age) in UserInfoDto
 * The other 2 Parameters   workYear,workAddress   Assigned to 2 attributes (workyear, workaddress) in WorkInfoDto
 *
 * @param userInfoDto
 * @param workInfoDto
 * @return
 */
@RequestMapping("/receiveparam/test5.do")
public ModelAndView test5(UserInfoDto userInfoDto, WorkInfoDto workInfoDto) {
    String msg = String.format("userInfoDto: [%s], workInfoDto: [%s]", userInfoDto, workInfoDto);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

8. Composite objects receive parameters (nested objects in objects, collections, etc.)

The following form

<form method="post" action="receiveparam/test6.do">

    full name:"userInfo.name" value="Passerby"/> 

    Age:"userInfo.age" value="30"/>


    Working years:"workInfo.workYears" value="10"/> 

    Age:"workInfo.workAddress" value="Shanghai"/>


    First job company:<input name="experienceInfos[0].company" value="Baidu"/> 

    Position 1:<input name="experienceInfos[0].position" value="Java development"/> 


    Second job company:<input name="experienceInfos[1].company" value="Ali"/> 

    2nd position:<input name="experienceInfos[1].position" value="Java Senior Developer"/> 


    <input type="submit" value="Submit">

</input type=</input name=</input name=</input name=</input name=</form method=

Corresponding controller

@RequestMapping("/receiveparam/test6.do")
public ModelAndView test6(UserDto userDto) {
    String msg = String.format("userDto: [%s]", userDto);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

The focus is on the structure of the method parameter UserDto

/**
 * User information
 */
public class UserDto {
    //Basic personal information
    private UserInfoDto userInfo;
    //Work information
    private WorkInfoDto workInfo;
    //Work experience (0 to n)
    private List experienceInfos;

    //get and set methods are omitted

    @Override
    public String toString() {
        return "UserDto{" +
                "userInfo=" + userInfo +
                ", workInfo=" + workInfo +
                ", experienceInfos=" + experienceInfos +
                '}';
    }
}

There are three properties, two objects and a List collection in the UserDto class. Let's take a look at the code of these three classes

/**
 * Basic user information
 */
public class UserInfoDto {
    //full name
    private String name;
    //Age
    private Integer age;

     //get and set methods are omitted

    @Override
    public String toString() {
        return "UserModel{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

/**
 * Basic work information
 */
public class WorkInfoDto {
    //Working years
    private Integer workYears;
    //Duty station
    private String workAddress;

 //get and set methods are omitted

    @Override
    public String toString() {
        return "WorkInfoDto{" +
                "workYears=" + workYears +
                ", workAddress='" + workAddress + '\'' +
                '}';
    }
}

/**
 * hands-on background
 */
public class ExperienceInfoDto {
    //company
    private String company;
    //position
    private String position;

    //get and set methods are omitted

    @Override
    public String toString() {
        return "ExperienceInfoDto{" +
                "company='" + company + '\'' +
                ", position='" + position + '\'' +
                '}';
    }
}

Here, we mainly pay attention to the transmission method of the following set data. The name in the form needs to have a subscript, starting from 0, as shown in the following figure:

9. Accept parameters in url through @ PathVariable

Sometimes the URLs we request are as follows. One is dynamic, that is, the part after / userInfo / is userId. We don't know the specific value of userId. What should we do at this time?

/userInfo/1
/userInfo/2
/userInfo/3
/userInfo/4
...
/userInfo/{userId}

In this case, polymorphic URLs can be used. For example, the following controller code. Note that the value value of the @ RequestMapping annotation is / receiveparam/{v1}/{v2}.do. The part wrapped by {} is the dynamic part. The value of the dynamic part of the url can be obtained through @ PathVariabl in the method parameters.

/**
 * Dynamic url: the {variable name} can be used in the url to represent the dynamic part, and the part of the {} package can be replaced with any content
 * For example: / receiveparam/{v1}/{v2}.do is acceptable: / receiveparam/1/2.do, / receiveparam / passers-by / 30.do, etc
 * @PathVariable("Variable name ") can get the content of the dynamic part of the url and assign it to the formal parameter of the method
 * For example, the current method receives a request: / receiveparam / passerby / 30.do
 * Then the value of the first parameter p1 of the method is: passerby
 * Position 30 of the second parameter p2
 *
 * @param p1
 * @param p2
 * @return
 */
@RequestMapping("/receiveparam/{v1}/{v2}.do")
public ModelAndView test7(@PathVariable("v1") String p1, @PathVariable("v2") String p2) {
    String msg = String.format("p1: [%s],p2: [%s]", p1, p2);
    System.out.println(msg);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/WEB-INF/view/result.jsp");
    modelAndView.addObject("msg", msg);
    return modelAndView;
}

Correspondence between request and value

Request urlValue of method parameter p1Value of method parameter p2
/receiveparam / passerby / 30.doPasserby30
/receiveparam/1/2.do12

The above methods of accepting parameters can be combined, such as the following. There are servlet objects and custom objects at the same time

@RequestMapping("/receiveparam/test8.do")
public ModelAndView test8(HttpServletRequest request, HttpServletResponse response, UserDto userDto)

10. Case code and test case

10.1 code address

https://gitee.com/javacode2018/springmvc-series

You can download it and deploy it to tomcat to run and view the results of each case above.

10.2 the case code has two operation modes

10.2.1. Mode 1: view the effect in the browser

Deploy the chat02 receiveparam module to tomcat, and then visit the home page to see the case, as shown in the following figure

http://localhost:8080/chat02/

10.2.2. Mode 2: view the effect through HTTP Client

Run the test cases through the HTTP Client in idea. Friends who don't know the usage of HTTP Client can move: an extremely efficient interface test tool, HTTP Client

As shown in the following figure, the HTTP Client test case codes are in chat02-receiveparam/src/test/resources/ReceiveParamController.http

The next article will introduce the reception and principle of json format data

Topics: Java Spring