Java Web Learning (5) - Spring MVC's data binding

Spring MVC's data binding

Binding data is bound to one characteristic of the user input field model.
Http request data transmitted to a String, through data binding, data may be filled with different types of object properties.

The basic type binding

@RequestMapping("/int")
@ResponseBody
public String bindInt (int i) {
    return "bindInt:" + i;
}

Request:? / Int i = 10
in response to: bindInt: 3

Bad request: / int or / int 2?
Error Code: 500

When the basic types of data binding, it must pass keyand value.

Package Type Bind

@RequestMapping("/integer")
@ResponseBody
public String bindInteger (Integer i) {
    return "bindInteger:" + i;
}

Request:? / Integer i = 5
in response to: bindInteger: 5

请求:/integer or /integer?5 or /integer?i or /integer?i=
响应:bindInteger:null

The type of packaging data binding, keyand valuecan be empty.
If the required parameters must be passed, it can be added @RequestParam.

@RequestMapping("/integer")
@ResponseBody
public String bindInteger (@RequestParam Integer i) {
    return "bindInteger:" + i;
}

Bad request: / integer or / integer 5?
Error Code: 400

Request:?? / Integer i or / integer i =
response: bindInteger: null

Array bind

@RequestMapping("/array")
@ResponseBody
public String bindArray (String[] strs) {
    StringBuilder sb = new StringBuilder();
    sb.append("bindArray:");
    for (String str : strs)
        sb.append(str + " ");
    return sb.toString();
}

Request:? / Array strs = str1 & strs = str2
response: bindArray: str1 str2

Simple Object bind

@RequestMapping("/user")
@ResponseBody
public String bindUser (User user) {
    return "bindUser:" + user.toString();
}
public class User {
    private String name;
    private Integer age;
    // getters and setters
    // toString
}

Request:? / User name = Tom & age = 15
Response: bindUser: User [name = Tom , age = 15]

Multi-level object bound

public class User {
    private String name;
    private Integer age;
    private ContactInfo info;
    // getters and setters
    // toString
}
public class ContactInfo {
    private String phone;
    private String address;
    // getters and setters
    // toString
}

Request:? / User name = Tom & info.phone = 123456
response: bindUser: User [name = Tom , age = null, info = ContactInfo [phone = 123456, address = null]]

With multi-object binding properties

@RequestMapping("/userandadmin")
@ResponseBody
public String bindUserAndAdmin (User user, Admin admin) {
    return "bindUserAndAdmin:\n" + user.toString() + "\n" + admin.toString();
}
public class Admin {
    private String name;
    private Integer age;
    // getters and setters
    // toString
}

Request: / userandadmin name = Tom & age = 15?
Response:
bindUserAndAdmin:
the User [name = Tom, Age = 15]
the Admin [name = Tom, Age = 15]

While the data is bound to the two objects have the same properties.
Solution:

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

@InitBinder("admin") 
public void initAdmin(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("admin.");
}

Request:? / Userandadmin user.name = Tom & age = 15 & admin.name = Jack
response:
bindUserAndAdmin:
the User [name = Tom, Age = 15]
the Admin [name = Jack, Age = 15]

InitBinderIn the role of the controller, the controller first call into the InitBindercall back RequestMappingmethod.
Not configured InitBinderprefix invalid and can not successfully bind.

WebDataBinderParameter used to bind to a specific request JavaBean.

List Binding

@RequestMapping("/stringlist")
@ResponseBody
public String bindStringList (@RequestParam("name") List<String> strs) {
    return "bindStringList:" + strs.toString();
}

Request: / stringlist name = Tom & name = Jack?
Response: bindStringList: [Tom, Jack]

@RequestMapping("/userlist")
@ResponseBody
public String bindUserList(UserListForm userListForm){
    return "bindUserList:\n" + usersModel.toString();
}
public class UserListForm {
    private List<User> list;
    // getters and setters
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (User u : users)
            sb.append(u.toString() + "\n");
        return sb.toString();
    }
}

请求:/userlist?users[0].name=Tom&users[2].name=Jack
响应:
bindList:
User [name=Tom, age=null]
User [name=null, age=null]
User [name=Jack, age=null]

PS: High version of the tomcat [need to escape %5B, ]need to escape to%5D

Set Binding

Set the List Binding basically the same, but in use Set<User>, the need to initialize the Set capacity.

public class UserSetForm {
    private Set<User> users;
    private UserSetForm () {
        // 设置 set 容量为 2 不能访问 size 外的对象
        // 如果覆盖了 User 的 equals 和 hashcode 方法 则 set 容量为 1
        users = new HashSet<User>();
        users.add(new User());
        users.add(new User());
        System.out.println(users.size());
    }
    // getters and setters
    // toString
}
// User.java
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((age == null) ? 0 : age.hashCode());
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    User other = (User) obj;
    if (age == null) {
        if (other.age != null)
            return false;
    } else if (!age.equals(other.age))
        return false;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

Request:? / Userset users [0] .name = Tom
response:
bindUserSet:
the User [name = Tom, Age = null]

Error Request:? / Userset users [0] .name = Tom & users [1] .name = Jack
Error Code: 500
Error Description: Can not get element with index 1 from Set of size 1, accessed using property path 'users [1]'

Map bindings

@RequestMapping("/usermap")
@ResponseBody
public String bindUserMap (UserMapForm userMapForm) {
    return "bindUserMap:\n" + userMapForm.toString();
}
public class UserMapForm {
    private Map<String, User> users;
    // getters and setters
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (String s : users.keySet())
            sb.append("Users[" + s + "] = " + users.get(s) + "\n");
        return sb.toString();
    } 
}

请求:/usermap?users[x].name=Tom&users[y].name=Jack
响应:
bindUserMap:
Users[x] = User [name=Tom, age=null]
Users[y] = User [name=Jack, age=null]

JSON binding

@RequestMapping("/userjson")
@ResponseBody
public String bindUserJson (@RequestBody User user) {
    return "bindUserJson:" + user.toString();
}

请求:
Content-Type:application/json
Body:

{
    "name":"Tom",
    "age":15
}  

Response: bindUserJson: User [name = Tom , age = 15]
dependency: jackson-databind

XML Binding

@RequestMapping("/userxml")
@ResponseBody
public String bindUserXml (@RequestBody User user) {
    return "bindUserXml:" + user.toString();
}
@XmlRootElement(name="user")
public class User {   
    private String name;
    private Integer age;
    @XmlElement(name="name")
    public String getName() {
        return name;
    }
    @XmlElement(name="age")
    public Integer getAge() {
        return age;
    }
    // setters
    // toString
}

Request:
the Content-the Type: file application / XML
Body:

<user>
  <name>Tom</name>
  <age>15</age>
</user> 

Response: bindUserXml: User [name = Tom , age = 15]
dependency: jaxb-api jaxb-impl spring -oxm

PropertyEditor

public interface PropertyEditor {
    void setValue(Object value);
    Object getValue();
    String getAsText();
    void setAsText(String text) throws java.lang.IllegalArgumentException;
    // ...
}

Use: general use of the built or inherited PropertyEditorSupport(implements PropertyEditor), with the WebDataBindertopical use.

@RequestMapping("/datepe")
@ResponseBody
public String bindDateByPropertyEditor (Date date1) {
    return date1.toString();
}

@InitBinder("date1")
public void initDate (WebDataBinder binder) {
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}

Request:? / Datepe date1 = 2019-11-11
Response: Mon Nov 11 00:00:00 CST 2019

Formatter

public interface Formatter<T> extends Printer<T>, Parser<T> {

}
public interface Printer<T> {
    String print(T object, Locale locale);
}
public interface Parser<T> {
    T parse(String text, Locale locale) throws ParseException;
}

Use: Source type String, can be global or local use.

@RequestMapping("/dateformatter")
@ResponseBody
public String bindDateByFormatter (Date date2) {
    return date2.toString();
}
<mvc:annotation-driven conversion-service="formatter"/>
<!-- conversion-service 与 id 对应 -->
<bean id="formatter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="formatters">
        <set>
            <bean class="org.springframework.format.datetime.DateFormatter">
                <constructor-arg name="pattern" value="yyyy-MM-dd" />
            </bean>
        </set>
    </property>
</bean>

Request:? / Dateformatter date2 = 2019-12-12
Response: Thu Dec 12 00:00:00 CST 2019

Converter

public interface Converter<S, T> {
    @Nullable
    T convert(S source);
}

Use: Built implemented as a final class, not extensible, customizable source type and destination type, global or local use.

@RequestMapping("/dateconverter")
@ResponseBody
public String bindDateByConverter (Date date3) {
    return date3.toString();
}
public class DateConverter implements Converter<String, Date> {
    public Date convert(String source) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return format.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}
<mvc:annotation-driven conversion-service="converter"/>
<!-- 自定义 Converter 类 -->
<bean id="converter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="common.DateConverter" />
        </set>
    </property>
</bean>

Request:? / Dateconverter date3 = 2019-10-24
Response: Thu Oct 24 00:00:00 CST 2019





Reference: SpringMVC data binding entry

Guess you like

Origin www.cnblogs.com/JL916/p/11883298.html