简体   繁体   English

如何更改单值 java 对象的 JSON 表示?

[英]How to change JSON representation for single value java object?

I had a class like:我有一个像这样的类:

public class EmailAddress {
   public String value;

   public String tld() {...}
   public String host() {...}
   public String mailbox() {...}
}

Now I use this class in an Object / Entity:现在我在一个对象/实体中使用这个类:

@Entity
public class Customer {
    public String name;
    public EmailAddress mail;
}

Now, when I do a rest service for Customer , I get this format:现在,当我为Customer提供休息服务时,我得到以下格式:

{
    "id": 1,
    "name": "Test",
    "email": {
        "value": "test@test.de"
    }
}

But I only want "email": "test@test.de"但我只想要"email": "test@test.de"

{
    "id": 1,
    "name": "Test",
    "email": "test@test.de"
}

What I must do?我应该做什么? I use Spring Boot and Hibernate Entities.我使用 Spring Boot 和 Hibernate 实体。

Thank you for any support感谢您的支持

You should use DTO class in request handling and make mappings from DTO to Entity and backwards, eg:您应该在请求处理中使用 DTO 类,并进行从 DTO 到实体和向后的映射,例如:

public class CustomerDTO {
    private Integer id;
    private String name;
    private String email;
}

You should use DataTransferObjects for your (REST) APIs.您应该为您的 (REST) API 使用DataTransferObjects The DTOs only contain the fields the interface should provide (or receive). DTO 仅包含接口应提供(或接收)的字段。

When receiving objects from the client and before returning the object from your Controller you can convert the DTOs to your domain model (Which could be your JPA entites classes).从客户端接收对象时,在从控制器返回对象之前,您可以将 DTO 转换为您的域模型(可以是您的 JPA 实体类)。

Example for a controller method.控制器方法的示例。 We assume you get an object from an user-editor which contains all data you want to update in your database-objects and return the updated company DTO:我们假设您从用户编辑器获得一个对象,其中包含您要在数据库对象中更新的所有数据,并返回更新后的公司 DTO:

@PutMapping
public CustomerDto updateCustomer(CustomerEditorDto updatedCustomerDto) {
    Customer updatedCustomer = CustomerConverter.convert(updatedCustomerDto);
    updatedCustomer = customerService.updateCustomer(updatedCustomer);
    return CustomerConverter.convert(updatedCustomer);
}

and your Converter class:和你的转换器类:

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CustomerConverter {

    public static CustomerDto convert(Customer customer) {
        CustomerDto result = null;
        if (customer != null) {
            // TODO: set fields in result-dto
        }
        return result;
    }

    public static Customer convert(CustomerEditorDto customer) {
        Customer result = null;
        if (customer != null) {
            // TODO set fields in result;
        }
        return result;
    }
}

and here are the DTOs这是 DTO

@Getter
@Setter
public class CustomerDto {
    private Integer id;
    private String name;
    private String email;
}

@Getter
@Setter
public class CustomerEditorDto {
    private Integer id;
    private String firstName;
    private String lastName;
    private String email;
    private String otherPropertyOrStuff; 
}

This way you can separate the API modell from your JPA entites.这样您就可以将 API 模型与 JPA 实体分开。 You can use the same models for input/output.您可以对输入/输出使用相同的模型。 And you can even use a different model to work with inside your services and the finally convert them into your JPA entites, before persisting the data (or after reading the data).您甚至可以在您的服务内部使用不同的模型,并在持久化数据之前(或读取数据之后)最终将它们转换为您的 JPA 实体。

There are tools which can take care of the conversion, like mapstruct .有一些工具可以处理转换,比如mapstruct

* The above annotations @Getter , @Setter , ... are from project lombok and very are handy to generate boiler-plate code automatically. * 以上注解@Getter , @Setter , ... 来自@Setter项目,非常方便自动生成样板代码。

I found an other easier solution, use a JsonSerializer on the entity Property:我找到了另一个更简单的解决方案,在实体属性上使用 JsonSerializer:

@JsonSerialize(using = EmailAddressSerializer.class)
private EmailAddress email;

The serializer class:序列化器类:

public class EmailAddressSerializer extends StdSerializer<EmailAddress> {

    public EmailAddressSerializer() {
        super(EmailAddress.class);
    }

    protected EmailAddressSerializer(Class<EmailAddress> t) {
        super(t);
    }

    @Override
    public void serialize(EmailAddress email,
                          JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(email.value);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM