如何根据 spring 引导中每个 @JsonView 的 rest 方法将不同的名称映射到 json 属性?
How to map different name to json property based on rest method per @JsonView in spring boot?
我有 2 组其余 APIs 使用 Spring 引导实现,使用相同的 Java POJO class。基于 API,我必须 return 不同的字段并为少数字段使用不同的名称。目前我正在为一组 API 使用@JsonView。但我还需要为该@JsonView 指定不同的名称。
例如:对于 @JsonView,字段 'host' 需要命名为 'ip',而对于其他 API,则需要命名为 'host'。
我不确定如何根据@JsonView 映射不同的 属性 名称。
我检查了一些结果,比如使用 MixIns。但不确定如何在 Spring Boot Rest API 中执行操作,尤其是在方法级别。
public class Con {
@JsonView(View.ConInfo.class)
private String host;
private String name;
}
控制器方法:
@JsonView(View.ConInfo.class)
@GetMapping
public Con getConInfo() {}
@GetMapping("/raw")
public Con getCon() {}
预计:
{"ip":"10xxx"} 对于 getConInfo API
{"host":"10xxx", "name":"con1"} 对于 getCon API.
实际:
为 getConInfo API
获取 {"host":"10xxx"}
当然有办法实现您想要的(请参阅下面的详细信息)。 但我鼓励你避免它。
由于您有不同的 有效载荷,因此您应该有不同的 类 来表示每个有效载荷。
如果您仍想沿用原来的路径,可以定义两个视图:
public interface Views {
interface Summary { }
interface Details { }
}
然后按如下方式注释您的有效载荷:
@Data
public class Payload {
@JsonIgnore
private String host;
@JsonView(Views.Details.class)
private String name;
@JsonView(Views.Summary.class)
public String getIp() {
return host;
}
@JsonView(Views.Details.class)
public String getHost() {
return host;
}
}
现在考虑下面的方法,注释为@JsonView(Views.Summary.class)
@JsonView(Views.Summary.class)
@GetMapping(path = "/summary", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Payload> getSummary() {
Payload payload = new Payload();
payload.setHost("0.0.0.0");
payload.setName("example");
return ResponseEntity.ok(payload);
}
它将产生:
{
"ip": "0.0.0.0"
}
现在考虑以下用 @JsonView(Views.Details.class)
注释的方法:
@JsonView(Views.Details.class)
@GetMapping(path = "/details", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Payload> getDetails() {
Payload payload = new Payload();
payload.setHost("0.0.0.0");
payload.setName("example");
return ResponseEntity.ok(payload);
}
它将产生:
{
"host": "0.0.0.0",
"name": "example"
}
根据您对问题的描述,
你做错了,
也许,
其实不知道自己想要什么
- 你有两个不同的 JSON 结构。
- 您想根据 return 发送 JSON 的方法发送不同的 JSON。
- 每个方法都会return一个JSON结构。
- 您的数据 "maps" 到两种不同的结构。
您似乎已经拥有一个 class 中表示的数据(可能用于访问数据库);
我将其称为 VO class
试试这个:
- 为每个 JSON 结构创建一个 class(两个不同的 classes,
一个有主机名,一个有 IP)。
- 在JSON中用Jackson来表示这个class(你在做这个)
- 创建一个映射器以从 VO 获取数据并创建选择的 JSON class。
这可以像
DataMapper.makeHostnameJsonClass
和 DataMapper.makeIPJsonClass
. 一样简单
- 使用网络处理程序中的映射器 return 正确的 JSON class.
- 将每个 Web 处理程序声明为 return 正确的 JSON class。
我有 2 组其余 APIs 使用 Spring 引导实现,使用相同的 Java POJO class。基于 API,我必须 return 不同的字段并为少数字段使用不同的名称。目前我正在为一组 API 使用@JsonView。但我还需要为该@JsonView 指定不同的名称。 例如:对于 @JsonView,字段 'host' 需要命名为 'ip',而对于其他 API,则需要命名为 'host'。 我不确定如何根据@JsonView 映射不同的 属性 名称。
我检查了一些结果,比如使用 MixIns。但不确定如何在 Spring Boot Rest API 中执行操作,尤其是在方法级别。
public class Con {
@JsonView(View.ConInfo.class)
private String host;
private String name;
}
控制器方法:
@JsonView(View.ConInfo.class)
@GetMapping
public Con getConInfo() {}
@GetMapping("/raw")
public Con getCon() {}
预计: {"ip":"10xxx"} 对于 getConInfo API
{"host":"10xxx", "name":"con1"} 对于 getCon API.
实际: 为 getConInfo API
获取 {"host":"10xxx"}当然有办法实现您想要的(请参阅下面的详细信息)。 但我鼓励你避免它。
由于您有不同的 有效载荷,因此您应该有不同的 类 来表示每个有效载荷。
如果您仍想沿用原来的路径,可以定义两个视图:
public interface Views {
interface Summary { }
interface Details { }
}
然后按如下方式注释您的有效载荷:
@Data
public class Payload {
@JsonIgnore
private String host;
@JsonView(Views.Details.class)
private String name;
@JsonView(Views.Summary.class)
public String getIp() {
return host;
}
@JsonView(Views.Details.class)
public String getHost() {
return host;
}
}
现在考虑下面的方法,注释为@JsonView(Views.Summary.class)
@JsonView(Views.Summary.class)
@GetMapping(path = "/summary", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Payload> getSummary() {
Payload payload = new Payload();
payload.setHost("0.0.0.0");
payload.setName("example");
return ResponseEntity.ok(payload);
}
它将产生:
{
"ip": "0.0.0.0"
}
现在考虑以下用 @JsonView(Views.Details.class)
注释的方法:
@JsonView(Views.Details.class)
@GetMapping(path = "/details", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Payload> getDetails() {
Payload payload = new Payload();
payload.setHost("0.0.0.0");
payload.setName("example");
return ResponseEntity.ok(payload);
}
它将产生:
{
"host": "0.0.0.0",
"name": "example"
}
根据您对问题的描述, 你做错了, 也许, 其实不知道自己想要什么
- 你有两个不同的 JSON 结构。
- 您想根据 return 发送 JSON 的方法发送不同的 JSON。
- 每个方法都会return一个JSON结构。
- 您的数据 "maps" 到两种不同的结构。
您似乎已经拥有一个 class 中表示的数据(可能用于访问数据库); 我将其称为 VO class 试试这个:
- 为每个 JSON 结构创建一个 class(两个不同的 classes, 一个有主机名,一个有 IP)。
- 在JSON中用Jackson来表示这个class(你在做这个)
- 创建一个映射器以从 VO 获取数据并创建选择的 JSON class。
这可以像
DataMapper.makeHostnameJsonClass
和DataMapper.makeIPJsonClass
. 一样简单
- 使用网络处理程序中的映射器 return 正确的 JSON class.
- 将每个 Web 处理程序声明为 return 正确的 JSON class。