返回一个带有数据的 JSON 格式消息给客户端 – Java/Spring/REST

huangapple go评论73阅读模式
英文:

Returning a message for the client in json format along with data - Java/Spring/REST

问题

我想要返回一个自定义消息以及我的端点应以 json 格式返回的数据。例如:

{
  "id": "1",
  "name": "John",
  "surname": "Jackson",
  "city": "Los Angeles",
  "message": "在所选类别中只有1个人"
}

所以我的 person 类的 POJO 类有字段:idnamesurnamecity。然而,我也想返回消息,以便客户端应用程序可以在前端显示消息。我正在寻找解决方案。默认情况下,Controller 端点可以返回对象为 json,没有问题。但这只会给我数据、200 状态,仅此而已。我了解到可以返回 ResponseEntity,但这也没有解决问题,因为在响应体中它接受一个 POJO,所以我仍然无法发送自定义消息和数据。我需要发送自定义消息、数据以及适当的状态代码。

英文:

I would like to return a custom message along with data that my endpoint is supposed to return in json format. E.g:

{
 "id": "1",
 "name": "John",
 "surname": "Jackson",
 "city": "Los Angeles"
 "message": "There was only 1 person in chosen category"
}  

So my POJO class of person has fields: id, name, surname, city. However I would like to return message too, so the client application can display the message on the front-end. I was looking for a solution. By default Controller endpoint can return the object as json no problem. But that just gives me data, 200 status and that's it. I found about returning ResponseEntity, but this doesn't solve the problem either since in response body it takes a POJO so I still can't send a custom message along with data. I need to send custom message, data and a proper status code.

答案1

得分: 2

你可以创建一个通用的类,从你的控制器中返回该类,它将通过 `message` 属性为你的模型添加额外信息:

```java
public class ServerResponse {
    @JsonUnwrapped
    private final Object wrapped;
    private final String message;

    public ServerResponse(Object wrapped, String message) {
        this.wrapped = wrapped;
        this.message = message;
    }
    //getters
}

然后,你可以在构造函数中传递任何对象给这个类,让 Jackson 处理序列化。这样,你就不需要为每个模型创建一个新的类:

User user = new User("1", "John", "Jackson", "Los Angeles");
ServerResponse serverResponse = new ServerResponse(user, "There was only 1 person in chosen category");

当你从控制器返回 ServerResponse 时,它将被序列化为:

{
   "id":"1",
   "name":"John",
   "surname":"Jackson",
   "city":"Los Angeles",
   "message":"message"
}

<details>
<summary>英文:</summary>

You can create a generic class that you will return from your controllers which will enrich your models with `message` property :

public class ServerResponse {
@JsonUnwrapped
private final Object wrapped;
private final String message;

public ServerResponse(Object wrapped, String message) {
    this.wrapped = wrapped;
    this.message = message;
}
//getters

}

and then you can pass any object to this class in the constructor and let Jackson handle the serialization for you. This way you do not have to create a new class per your model :

User user = new User("1", "John", "Jackson", "Los Angeles");
ServerResponse serverResponse = new ServerResponse(user, "There was only 1 person in chosen category");

and when you return `ServerResponse` from the controller it will be serialized to :

{
"id":"1",
"name":"John",
"surname":"Jackson",
"city":"Los Angeles",
"message":"message"
}


</details>



# 答案2
**得分**: 1

尝试创建一个新的辅助类(CustomUser),其中包含id、name、surname、city和message字段(具有getter和setter方法)。在您的控制器中,当收到用户(具有属性的新用户)时,创建CustomUser类的新实例,设置属性,然后发送customUser,就像这样:

```java
CustomUser customUser = new CustomUser();
customUser.setId(user.getId());
customUser.setName(user.getName());
customUser.setSurname(user.getSurname());
customUser.setCity(user.getCity());
customUser.setMessage("自定义消息");
```


<details>
<summary>英文:</summary>

Try to create new helper class(CustomUser) that have id, name, surname, city, message fields(getters and setters). And on sending you the user(new User with properties) on your controller, create new Instance of CustomUser class, set properties, and send customUser,
Like this:

    CustomUser customUser = new CustomUser();
    customUser.setId(user.getId);
    customUser.setName(user.getName);
    customUser.setSurname(user.getSurname);
    customUser.setCity(user.getCity);
    customUser.setMessage(&quot;Custom message&quot;);

</details>



# 答案3
**得分**: 1

你可以使用 @MappedSuperclass 和 @Transient 来解决你的需求。

因此,你会有一个像这样的基类:

```java
@MappedSuperclass
@Data
public class BaseEntity {
	
	@Transient
	private String message; 
    
}
```

而你的客户类会是这个样子:

```java
@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "customer")
public class Customer extends BaseEntity {

    @Id
    private Integer id;
    private String name;
    private String surname;
    private String city;
}
```

这样,你可以将这个字段添加到你所有的实体中。

<details>
<summary>英文:</summary>

You could use @MappedSuperclass and @Transient to solve your requirement.

Therefore you would have a base class like this:

    @MappedSuperclass
    @Data
    public class BaseEntity {
	
    	@Transient
    	private String message; 
    
    }

And your customer class would look like this:

    @Data
    @EqualsAndHashCode(callSuper = false)
    @Entity
    @Table(name = &quot;customer&quot;)
    public class Customer extends BaseEntity {
    
	    @Id
	    private Integer id;
	    private String name;
    	private String surname;
    	private String city;
    }

This way you can add this field to all of your entities. 

</details>



huangapple
  • 本文由 发表于 2020年4月4日 18:19:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/61026660.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定