消除重复的 Json 元素并检索以大写字母开头的元素名称 spring boot/java
Eliminate duplicate Json elements and retrieve element names starting with capital letters spring boot/java
我正在使用 Spring 引导和 Spring 框架开发 Rest 客户端 (spring-boot-starter-parent 2.1.6.RELEASE)
我有一个 class 代表响应对象,如下所示:
public class ValidateResponse {
private String ResponseCode;
private String ResponseDesc;
//getters and setters
//constructors using fields
//empty constructor
}
我正在为外部 api 创建一个网络挂钩,我需要 return 一个 JSON 对象到一个特定的端点(JSON 对象属性必须以大写字母开头)。我正在从嵌套在 RequestMapping
根路径中的 PostMapping
方法调用 returning 对象:
@PostMapping("hooks/validate")
public ValidateResponse responseObj(@RequestHeader Map<String, String> headersObj) {
ValidateResponse response = new ValidateResponse("000000", "Success");
logger.info("Endpoint = hooks/validate | Request Headers = {}", headersObj);
return response;
}
但是,当我从邮递员那里到达终点时,我得到了重复的变量
{
"ResponseCode": "000000",
"ResponseDesc": "Success",
"responseCode": "000000",
"responseDesc": "Success"
}
我知道 pojo-json 转换是由 spring 处理的,但我不明白为什么转换会产生重复变量。
注意: 我知道 ResponseDesc
和 ResponseCode
没有使用最好的变量命名标准 (camelCasing) 声明。
我已经做了一些挖掘并根据 Java Language Specification
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
和
The "Java letters" include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ character should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems.
因此,我假设使用 Camelcase
格式定义变量在语法上是正确的 [需要对此进行说明]。
我正在考虑是否必须手动创建 JSON 对象,但我想先了解此行为的原因。任何指针表示赞赏。
public class ValidateResponse {
@JsonProperty("ResponseDesc")
public String responseCode;
@JsonProperty("ResponseDesc")
public String responseDesc;
//getters and setters
//constructors using fields
//empty constructor
}
这一定能解决您的问题,但我不知道原因,因为它需要 Jackson 进行深入调查。
编辑
我找到原因了。
该字段重复了,因为在你的情况下你有:
- 2 public 字段以大写命名 -> 它们将由 jackson
处理
- 2 getters
getResponseCode
和 getResponseDesc
-> 它们将被解决
相应地作为属性 responseCode
和 responseDesc
的访问器。
总而言之 - 您有 4 个属性由 Jackson 解决。只需将您的字段设为私有即可解决您的问题,但我仍然建议使用 JsonProperty
方法。
我在项目 pom.xml
文件中添加了一个 com.google.code.gson
依赖项来配置 Spring Boot 以使用 Gson(而不是默认的 jackson)。
从 hooks/validate
端点返回的 Json object 的 属性 名称必须以大写字母开头。使用 java class 生成响应 object 结果是 camelCased
属性 名称,所以我决定创建 JSON 响应 object 手动。这是创建自定义 JSON object:
的代码
public ResponseEntity<String> responseObj(@RequestHeader Map<String, String> headersObj) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
JsonObject response = new JsonObject();
response.addProperty("ResponseCode", "00000000");
response.addProperty("ResponseDesc" , "Success");
logger.info("Endpoint = hooks/validate | Request Headers = {}", headersObj);
return ResponseEntity.ok().headers(responseHeaders).body(response.toString());
}
注意 JSON object 作为 String
返回,因此端点的响应必须有一个额外的 header定义MediaType
通知调用系统响应是JSON格式:
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
然后将 header 添加到响应中:
return ResponseEntity.ok().headers(responseHeaders).body(response.toString());
Jackson
反序列化它遇到的所有 public 字段。但是,如果您希望 Jackson
到 return 预期元素名称中的响应(在您的情况下元素以大写字母开头),请将字段设为 private
并用 [=14= 注释它们].您的 class 文件通常如下所示
public class ValidateResponse {
@JsonProperty("ResponseDesc")
private String responseCode;
@JsonProperty("ResponseDesc")
private String responseDesc;
//getters and setters
//constructors using fields
//empty constructor
}
Note: The getters and setters for these fields should be public
, otherwise Jackson
won't see anything to deserialize in the class.
我正在使用 Spring 引导和 Spring 框架开发 Rest 客户端 (spring-boot-starter-parent 2.1.6.RELEASE) 我有一个 class 代表响应对象,如下所示:
public class ValidateResponse {
private String ResponseCode;
private String ResponseDesc;
//getters and setters
//constructors using fields
//empty constructor
}
我正在为外部 api 创建一个网络挂钩,我需要 return 一个 JSON 对象到一个特定的端点(JSON 对象属性必须以大写字母开头)。我正在从嵌套在 RequestMapping
根路径中的 PostMapping
方法调用 returning 对象:
@PostMapping("hooks/validate")
public ValidateResponse responseObj(@RequestHeader Map<String, String> headersObj) {
ValidateResponse response = new ValidateResponse("000000", "Success");
logger.info("Endpoint = hooks/validate | Request Headers = {}", headersObj);
return response;
}
但是,当我从邮递员那里到达终点时,我得到了重复的变量
{
"ResponseCode": "000000",
"ResponseDesc": "Success",
"responseCode": "000000",
"responseDesc": "Success"
}
我知道 pojo-json 转换是由 spring 处理的,但我不明白为什么转换会产生重复变量。
注意: 我知道 ResponseDesc
和 ResponseCode
没有使用最好的变量命名标准 (camelCasing) 声明。
我已经做了一些挖掘并根据 Java Language Specification
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
和
The "Java letters" include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ character should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems.
因此,我假设使用 Camelcase
格式定义变量在语法上是正确的 [需要对此进行说明]。
我正在考虑是否必须手动创建 JSON 对象,但我想先了解此行为的原因。任何指针表示赞赏。
public class ValidateResponse {
@JsonProperty("ResponseDesc")
public String responseCode;
@JsonProperty("ResponseDesc")
public String responseDesc;
//getters and setters
//constructors using fields
//empty constructor
}
这一定能解决您的问题,但我不知道原因,因为它需要 Jackson 进行深入调查。
编辑
我找到原因了。 该字段重复了,因为在你的情况下你有:
- 2 public 字段以大写命名 -> 它们将由 jackson 处理
- 2 getters
getResponseCode
和getResponseDesc
-> 它们将被解决 相应地作为属性responseCode
和responseDesc
的访问器。
总而言之 - 您有 4 个属性由 Jackson 解决。只需将您的字段设为私有即可解决您的问题,但我仍然建议使用 JsonProperty
方法。
我在项目 pom.xml
文件中添加了一个 com.google.code.gson
依赖项来配置 Spring Boot 以使用 Gson(而不是默认的 jackson)。
从 hooks/validate
端点返回的 Json object 的 属性 名称必须以大写字母开头。使用 java class 生成响应 object 结果是 camelCased
属性 名称,所以我决定创建 JSON 响应 object 手动。这是创建自定义 JSON object:
public ResponseEntity<String> responseObj(@RequestHeader Map<String, String> headersObj) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
JsonObject response = new JsonObject();
response.addProperty("ResponseCode", "00000000");
response.addProperty("ResponseDesc" , "Success");
logger.info("Endpoint = hooks/validate | Request Headers = {}", headersObj);
return ResponseEntity.ok().headers(responseHeaders).body(response.toString());
}
注意 JSON object 作为 String
返回,因此端点的响应必须有一个额外的 header定义MediaType
通知调用系统响应是JSON格式:
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
然后将 header 添加到响应中:
return ResponseEntity.ok().headers(responseHeaders).body(response.toString());
Jackson
反序列化它遇到的所有 public 字段。但是,如果您希望 Jackson
到 return 预期元素名称中的响应(在您的情况下元素以大写字母开头),请将字段设为 private
并用 [=14= 注释它们].您的 class 文件通常如下所示
public class ValidateResponse {
@JsonProperty("ResponseDesc")
private String responseCode;
@JsonProperty("ResponseDesc")
private String responseDesc;
//getters and setters
//constructors using fields
//empty constructor
}
Note: The getters and setters for these fields should be
public
, otherwiseJackson
won't see anything to deserialize in the class.