Begins with the introduction

In the SpringMVC part, the binding of parameters is not too much, rearranged it, as a supplement, time is in a hurry, there may be some mistakes, we can communicate together, discuss together!

Note: the following article, the focus is still on the use of parameter binding, about the guide package or some annotations, I did not say more, the previous article some commonly used are also introduced, if necessary, I will sort out a summary of annotations can also ha ~

Spring MVC step-by-step easy entry!

Juejin. Cn/post / 684490…

(I) Binding of basic type and packaging type parameters

Assuming that we want to request an age parameter, we have two options: pass in the basic type int and pass in the wrapper type Integer

Note: We focused on parameter bindings, I didn’t add the @requestMapping annotation on the project name or Controller

(1) Basic int

@RequestMapping("baseType.do")
@ResponseBody
public String baseType(int age) {
    return "age:" + age;
}
Copy the code

http://localhost:8080/baseType.do?age=30

When we request, we return the result: age:30

  • In this case, the key value must be passed in first. Otherwise, an error 500 is displayed indicating that the current age cannot be empty
  • Second, the parameter must be int. Otherwise, a 400 parameter exception error is reported

There is an annotation @requestParam that you should know about. Is there any way that the annotation’s required attribute can help us avoid the null request parameter problem?

The answer is no, although the annotation set required = false does not generate an error without passing a value. However, if a primitive data type is specified, such as int in our code, it still generates a 500 error without passing a value

Because it assigns null without passing a value, but int cannot be null

So to circumvent the null argument, we can choose the wrapper type Integer

(2) Packaging type

@RequestMapping("packingType.do")
@ResponseBody
public String packingType(Integer age) {
    return "age:" + age;
}
Copy the code

http://localhost:8080/packingType.do?age=30

Age :30 is normally returned

http://localhost:8080/packingType.do

http://localhost:8080/packingType.do?

http://localhost:8080/packingType.do?=

If the parameter is null, age:null is returned

  • The data received by the background is age= NULL
  • Therefore, in development, it is recommended to use wrapper types for data that may have empty parameters
  • Of course, we can also use the @requestParam annotation to set whether the request must include this parameter or not. This annotation defaults to saying that the parameter must be passed or an error will be reported

(2) Object parameter binding

(1) Binding of multi-level objects

What is a multilevel object, but let’s just do a very basic example, okay

Let’s start by creating a user class

public class User {
    private String id;
    privateString name; . Add the get set toString method}Copy the code

Simply write the corresponding User type in the parameter

@RequestMapping("objectType.do")
@ResponseBody
public String objectType(User user) {
    return user.toString();
}
Copy the code

http://localhost:8080/objectType.do?id=001&name=Steven

User{uid=’001′, name=’Steven’}

If at this point, I create a new class UserDetails

public class UserDetails {
    private Integer age;
    privateString address; . Add the get set toString method}Copy the code

How do you bind parameters when you introduce this class in the User class

public class User {
    private String id;
    private String name;
    
    privateUserDetails userDetails; . Add the get set toString method}Copy the code

http://localhost:8080/objectType.do?id=1&name=Steven&userDetails.age=20&userDetails.address=BeiJing

User{uid=’1′, name=’Steven’, userDetails= userDetails {age=20, address=’BeiJing’}}

  • For imported object member assignments, the format is as follows:userDetails.address=xxxxx
  • I did not use Chinese for the address here, because I returned it directly without encoding, otherwise it would be displayed. ?

(2) Binding with the parameters of the attribute object

If we want to receive two objects directly, sometimes we have to have the same members, such as in our User and Student classes

The Integer ID and String name are two members. Let’s try to request them

@RequestMapping("objectType2.do")
@ResponseBody
public String objectType2(User user, Student student) {
    return user.toString() + "" + student.toString();
}
Copy the code

http://localhost:8080/objectType2.do?id=8&name=Steven

User{id=’8′, name=’Steven’} Student{id=’8′, name=’Steven’}

As you can see, the values of both objects are assigned, but in most cases, the values of different objects are generally different, and there is a way around that

The @initBinder annotation helps us separate the bindings. The following code simply assigns a prefix to user and student, respectively

@InitBinder("user")
public void initUser(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("user.");
}

@InitBinder("student")
public void initStudent(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("stu.");
}
Copy the code

http://localhost:8080/objectType2.do?user.id=1&name=Steven&stu.id=002

When making such a request, we specify the ID values of user and student, respectively, and name is the same Steven

User{id=’1′, name=’Steven’, userDetails=null} Student{id=’2′, name=’Steven’}

(3) Array type parameter binding

@RequestMapping("arrayType.do")
@ResponseBody
public String arrayType(String[] nickname) {
    StringBuilder sb = new StringBuilder();
    for (String s : nickname) {
        sb.append(s).append(",");
    }
    return sb.toString();
}
Copy the code

http://localhost:8080/arrayType.do?nickname=Jack&nickname=Steven&nickname=Tom

Return result: Jack, Steven, Tom,

(4) Binding of set type parameters

(1) the type of the List

Collections cannot be directly parameter bound, so we need to create a class and bind the parameters to List in the class

First create the UserList class, where I just put private List

Users for demonstration purposes and add the get set toString method

In the control layer method, the parameter is the class created

@RequestMapping("listType.do")
@ResponseBody
public String listType(UserList userList) {
    return userList.toString();
}
Copy the code

http://localhost:8080/listType.do?users[0].id=1&users[0].name=Jack&users[1].id=2&users[1].name=Marry

Our request stores two user information separately into List< user > Users

Note: If your Tomcat version is around 7.0 then this is fine, but if it is a higher version, such as Tomcat 8.5 which I use myself, this will result in 400 errors

HTTP Status 400 – Bad Request

Message Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

This is because “[” and”] “cannot be used in the address of the higher version of Tomcat, we can replace them with the corresponding hexadecimal, that is,” [” with %5B, “] “with %5D

http://localhost:8080/listType.do?users%5B0%5D.id=1&users%5B0%5D.name=Jack&users%5B1%5D.id=2&users%5B1%5D.name=Marry

Or you can make a post request

(2) the Map types

We create a UserMap class and declare private map

Users to bind parameters
,user>

@RequestMapping("mapType.do")
@ResponseBody
public String mapType(UserMap userMap) {
    return userMap.toString();
}
Copy the code

http://localhost:8080/mapType.do?users['userA'].id=1&users['userA'].name=Jack&users['userB'].id=2&users['userB'].name=To m

“[]” also encounters the above error, so if you want to request access from the address bar, you either need to replace the character or issue a POST request

http://localhost:8080/mapType.do?users%5B%27userA%27%5D.id=1&users%5B%27userA%27%5D.name=Jack&users%5B%27userB%27%5D.id= 2&users%5B%27userB%27%5D.name=Tom

Returns the result: the UserMap {users = {userA = User {id = ‘1’, name = ‘Jack’}, userB = User {id = ‘2’, name = ‘Tom’}}}

(5) JSON parameter binding

In addition to forms and other forms of submission, there is an Ajax submission method that is often used to pass and receive JSON-formatted data to and from the back end. The following JAR package is used for converting JSON strings and objects

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.10.0</version>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.10.0</version>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.10.0</version>
</dependency>
Copy the code

To demonstrate this section, we create an Admin entity class

public class Admin {
    private Integer id;
    privateString name; . Add the get set toString method}Copy the code

(1) Binding of entity parameters

If the requested parameter has a matching entity class in the background, we can choose the foreground to pass a JSON to the background, which uses the matching entity class to receive it

JSON: {“id”: “37”,”name”: “zhang SAN “}

$(function () {$("#btn").click(function () {
		// Send an Ajax request
        $.ajax({
            url:"ajaxType1.do".contentType:"application/json".data:'{" id ":" 37 ", "name" : "* *"}'.dataType:"json".type:"post".success:function (data) {
            Parse the response dataalert(data.id); alert(data.name); }})}); });Copy the code

Contoller

// connect parameters with entities
@RequestMapping("ajaxType1.do")
@ResponseBody
public Admin ajaxType1(@RequestBody Admin admin) {
    System.out.println(admin.toString());
    admin.setName("Test Manager");
    return admin;
}
Copy the code

Admin in backend parameters is bound with parameters for developers to use

The @requestBody annotation is often used for content-type encoding that is not the default Application/X-www-form-urlcoded, and usually for application/ JSON

(2) Map parameter binding

There is also a case where there are still a lot of parameters in the request, but there is no appropriate entity in the background to match, we can also consider using map to receive

JSON: {“id”: “37”,”name”: “zhang SAN “}

$(function () {$("#btn").click(function () {
		// Send an Ajax request
        $.ajax({
            url:"ajaxType1.do".contentType:"application/json".data:'{" id ":" 37 ", "name" : "* *"}'.dataType:"json".type:"post".success:function (data) {
            Parse the response dataalert(data.id); alert(data.name); }})}); });Copy the code

But in Controller we use a map to receive, then simply give an instance, encapsulate the map value into an Admin object, and return it to the front end

@RequestMapping("ajaxType3.do")
@ResponseBody
public Admin ajaxType3(@RequestBody Map<String, String> map)  {
    Integer id = null;
    String name = null;

    if (map.containsKey("id")){
        id = Integer.parseInt(map.get("id"));
    }
    if (map.containsKey("name")){
        name = map.get("name");
    }

    Admin admin = new Admin();
    admin.setId(id);
    admin.setName(name);
    return admin;
}
Copy the code

(3) List parameter binding

Similarly, we can receive it as a list, which is passed as a JSON array

var listType=[];
var admin={};
admin.id=1;
admin.name='Tom';
listType.push(admin);

var admin2={};
admin2.id=2;
admin2.name='jack';
listType.push(admin2);

$(function () {$("#btn").click(function () {
		// Send an Ajax request
        $.ajax({
            url:"ajaxType1.do".contentType:"application/json".data:JSON.stringify(listType),
            dataType:"json".type:"post".success:function (data) {
            Parse the response dataalert(data.id); alert(data.name); }})}); });Copy the code

Take a look backstage

@RequestMapping("ajaxType5.do")
@ResponseBody
public void ajaxType5(@RequestBody List<Admin> list)  {

    System.out.println(list);

    for (Admin admin : list){
        System.out.println(admin.getId() + ""+ admin.getName()); }}Copy the code

Take a look at the console output:

[Admin {id = '1', name = 'Tom'}, Admin {id = '2', name = 'jack'}] 1 Tom 2 jackCopy the code

(4)

This is the form to submit

<form id="ajaxForm"  method="post">
    id:<input type="text" name="id">
    name:<input type="text" name="name">
</form>
Copy the code

$(“#ajaxForm”).serialize() this is an Ajax request. We also use $(“#ajaxForm”).serialize() to serialize a Form and submit it, but it just concatenates the Form serialization into a simple string, not JSON format, which looks something like this:

id=111&name=Steven
Copy the code

So the JSON stuff doesn’t work

$(function () {$("#btn").click(function () {
		// Send an Ajax request
        $.ajax({
            url:"ajaxType1.do".contentType:"application/json".data: $("#ajaxForm").serialize(),
            dataType:"json".type:"post".success:function (data) {
            Parse the response dataalert(data.id); alert(data.name); }})}); });Copy the code

If you want to use serialization and still want to pass the JSON format to the background, you can do it

We need to add a method

$.fn.serializeObject = function() {
	var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
    	if (o[this.name]) {
         	if(! o[this.name].push) {
            	o[this.name] = [o[this.name]];
             }
         	o[this.name].push(this.value || ' ');
         } else {
         	o[this.name] = this.value || ' '; }});return o;
};
Copy the code

Also change the data in ajax below to

 data:JSON.stringify($("#ajaxForm").serializeObject()),
Copy the code

You can get the JSON format in the background

{"id":"111"."name":"Steven"}
Copy the code

(6) XML parameter binding

The background is pretty simple, just like before, we need to do something in the entity, right

@RequestMapping("xmlType.do")
@ResponseBody
public String xmlType(@RequestBody Student student) {
    return student.toString();
}
Copy the code

In this case, we need to use a JAR package, Spring-OXm, which we can import ourselves

We then need to add @XMLRootelement and @XMLElement annotations to the accepted entity to represent the root and child nodes

package cn.ideal.Object;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "student")
public class Student {
    private Integer id;
    private String name;

    @XmlElement(name = "id")
    public Integer getId(a) {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @XmlElement(name = "name")
    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString(a) {
        return "Student{" +
                "id='" + id + '\' ' +
                ", name='" + name + '\' ' +
                '} '; }}Copy the code

For example, our XML is

<?xml version="1.0" encoding="UTF-8" ? >
<student>
	<id>66</id>
	<name>Steven</name>
</student>
Copy the code

Then make the request, noting that the Content-type is changed to Application/XML

Student{id=’66’, name=’Steven’}

(7) Ending

If there is any deficiency in the article, you are welcome to leave a message to exchange, thank friends for their support!

If it helps you, follow me! If you prefer the way of reading articles on wechat, you can follow my official account

We don’t know each other here, but we are working hard for our dreams

A adhere to push original development of technical articles of the public number: ideal more than two days