JSON 对象到 Java 对象的映射是如何完成的?

How the mapping of the JSON object to a Java object is done?

我已经使用 Postman API 客户端测试了 REST 服务,该客户端将 JSON 对象传递给服务。

JSON对象

{
    "username" : "user",
    "password" : "pass"
}

到 Java 对象的映射已正确完成并返回响应状态 200。

JSON 对象到 Java 对象的映射是如何在对 REST 服务方法的操作中完成的。

UserCl Class

static class UserCl{

        private String uname;
        private String password;
        private String name;

        public UserCl(){
        }

        public String getName() {
            return name;
        }

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

        public String getUsername() {
            return uname;
        }
        public void setUsername(String pusername) {
            this.uname = pusername;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String ppassword) {
            this.password = ppassword;
        }

    }

REST 服务方法

@PermitAll
@POST   
@Consumes(MediaType.APPLICATION_JSON)
@Path("/auth")
public Response login(UserCl usr){

    if(usr.getUsername().compareTo("user") == 0 && usr.getPassword().compareTo("pass") == 0){

    String usernameAndPassword = usr.getUsername() + ":" + usr.getPassword(); 

    try {               

            String base64String = Base64Encoder.encode(usernameAndPassword);
            System.out.println(base64String);                               

            return Response.status(200).build();


        } catch (IOException e) {           
            e.printStackTrace();        
            return Response.status(401).build();                
        }   
    }
    else{       
        return Response.status(401)build();
    }

}   

Resteasy 在后台默认使用 Jackson。基本行为(与大多数序列化框架的情况一样)是查找 JavaBean properties (getters/setters). For deserialization, the setters are introspected. They should follow JavaBean naming convention。如果你的情况

private String username;

public void setUsername(String string) {}

去掉方法名中的set,首字母小写。所以 setUsername 映射到 "username" JSON 属性.

序列化时,将使用吸气剂。就像反序列化一样,get 被剥离并且第一个字母小写。所以 getUsername 会在结果 JSON.

中添加 "username" 属性

也可以使用 Jackson 注释更改为 属性 名称。例如

@JsonProperty("name")
private String username;

但这需要您将 Jackson 作为编译时依赖项添加到您的项目中。

编辑

补充一下 Jackson,我们没有使用 JavaBean 属性。即使有 public 个字段,也会使用字段的名称。不太推荐,只是觉得我会把它扔出去。

一般使用反射实现。 Java 能够使用名称访问对象的方法和字段。这称为反射。在您的情况下,您正在使用的 JSON 库具有这种魔力。

首先它找到必须实例化的class。它从方法 login() 的参数类型中获取。它使用像

这样的代码创建实例
Class.forName("UserCl").newInstance()

(这需要 public 默认构造函数。您的 class 没有定义任何构造函数,因此隐含了一个默认构造函数。)

然后它发现 class UserCl,找到 setPassword()setUsername() 并调用它们传递适当的 JSON 属性的值。

有关 java 反射 API 的更多信息。