java - 一旦被 Lambda/Serverless 部署,就无法删除 JSON 中的“\”字符
java - Cannot get rid of '\' character in JSON once deployed by Lambda/Serverless
我正在创建一个 API(用 Java 编写),我正在通过无服务器部署它,它端口到 AWS Lambda 函数。 API 功能的所有方面都很棒,除了返回的请求在所有引号前面都包含“\”字符。
为了正确看待这个问题,我有一个人 class,其中包含名称 (String) 和心情 (String) 的实例变量。然后我有我的 class,它使用这个 class 来获取和创建一个 Person 对象,然后使用 Jackson 将其解析为 JSON 格式。这是返回到处理程序函数(对于 lambda)并显示为 "object body".
的内容
public class Person{
String name;
String mood;
//getters and setters and constructor
}
然后,稍后会有一些不同的class像
Person person = new Person("bob", "good");
这将被传递到我的方法中,该方法应该将东西转换为 JSON:
private String convStrToJson(Person person) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
return json;
}
如果我在输出中打印这个,我会得到类似的东西:
{"name":"bob","mood":"good"}
这是我想要和期待的。然而,当通过 GET 请求部署和调用时,结果是:
"{\"name\":\"bob\",\"mood\":\"good\"}"
我尝试了几种策略,包括对解析方法的补充,例如:
json = json.replace("\"", "");
从两个输出中完全删除引号,或者:
json = json.replace("\","");
完全没有效果。我还尝试将这两种方法都用作 replaceAll 方法,结果把事情搞得更糟了。我不确定我还能做些什么来摆脱这些 '\' 字符,我明白它们为什么在那里,但我不知道如何阻止它。感谢任何帮助。
只需使用 Google Gson java 库即可将 Java 对象转换为它们的 JSON 表示形式。
Gson gson = new Gson();
gson.toJson(person);
好的,我明白了。事实证明,无服务器不仅 包括 Jackson,而且实际上在它为处理响应而创建的布局中,"setObjectBody" 部分 将接受 any 种对象并使用 Jackson 将其解析为 JSON。这就是我搞砸的地方。我假设它只接受字符串,这是发生双重编码的地方。现在,如果我传入 Person 对象,serverless/Jackson 会为我适当地处理它并返回预期的输出。我将在下面包含代码片段以更好地演示此解决方案。 Serverless 创建了一个 'handler' class,它有一个模板,其中包含一个名为 handleRequest 的方法。填写后,class 现在看起来像这样:
public class GetStatusHandler implements RequestHandler<Map<String, Object>, ApiGatewayResponse> {
private static final Logger LOG = Logger.getLogger(GetStatusHandler.class);
@SuppressWarnings("unchecked")
public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) {
BasicConfigurator.configure();
LOG.info("received: " + input);
try {
Map<String, String> pathParameters = (Map<String, String>) input.get("queryStringParameters");
if(pathParameters == null) {
LOG.info("Getting details for all persons ");
PersonControl control = new PersonControl();
Person[] result = control.myGetHandler(context);
return ApiGatewayResponse.builder()
.setStatusCode(200)
.setObjectBody(result)
.setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
.build();
}else {
String name = pathParameters.get("name");
LOG.info("Getting details for "+name);
PersonControl control = new PersonControl();
Person result = control.myGetHandler(name, context);
return ApiGatewayResponse.builder()
.setStatusCode(200)
.setObjectBody(result)
.setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
.build();
}
}catch(Exception e) {
LOG.error(e, e);
Response responseBody = new Response("Failure getting person", null);
return ApiGatewayResponse.builder()
.setStatusCode(500)
.setObjectBody(responseBody)
.setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
.build();
}
}
}
并不是说当返回 ApiGatewayResponse(通过构建器)时,对象只是传递给 .setObjectBody 方法 ('result'),无服务器自动为我们转换为 JSON。而已!代码中不需要解析为 JSON。
响应可以是用户定义的对象,如下所示
class Handler implements RequestHandler<SQSEvent, CustomObject> {
public CustomObject handleRequest(SQSEvent event, Context context) {
return new CustomObject();
}
}
可以找到示例代码 here。
我正在创建一个 API(用 Java 编写),我正在通过无服务器部署它,它端口到 AWS Lambda 函数。 API 功能的所有方面都很棒,除了返回的请求在所有引号前面都包含“\”字符。
为了正确看待这个问题,我有一个人 class,其中包含名称 (String) 和心情 (String) 的实例变量。然后我有我的 class,它使用这个 class 来获取和创建一个 Person 对象,然后使用 Jackson 将其解析为 JSON 格式。这是返回到处理程序函数(对于 lambda)并显示为 "object body".
的内容public class Person{
String name;
String mood;
//getters and setters and constructor
}
然后,稍后会有一些不同的class像
Person person = new Person("bob", "good");
这将被传递到我的方法中,该方法应该将东西转换为 JSON:
private String convStrToJson(Person person) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
return json;
}
如果我在输出中打印这个,我会得到类似的东西:
{"name":"bob","mood":"good"}
这是我想要和期待的。然而,当通过 GET 请求部署和调用时,结果是:
"{\"name\":\"bob\",\"mood\":\"good\"}"
我尝试了几种策略,包括对解析方法的补充,例如:
json = json.replace("\"", "");
从两个输出中完全删除引号,或者:
json = json.replace("\","");
完全没有效果。我还尝试将这两种方法都用作 replaceAll 方法,结果把事情搞得更糟了。我不确定我还能做些什么来摆脱这些 '\' 字符,我明白它们为什么在那里,但我不知道如何阻止它。感谢任何帮助。
只需使用 Google Gson java 库即可将 Java 对象转换为它们的 JSON 表示形式。
Gson gson = new Gson();
gson.toJson(person);
好的,我明白了。事实证明,无服务器不仅 包括 Jackson,而且实际上在它为处理响应而创建的布局中,"setObjectBody" 部分 将接受 any 种对象并使用 Jackson 将其解析为 JSON。这就是我搞砸的地方。我假设它只接受字符串,这是发生双重编码的地方。现在,如果我传入 Person 对象,serverless/Jackson 会为我适当地处理它并返回预期的输出。我将在下面包含代码片段以更好地演示此解决方案。 Serverless 创建了一个 'handler' class,它有一个模板,其中包含一个名为 handleRequest 的方法。填写后,class 现在看起来像这样:
public class GetStatusHandler implements RequestHandler<Map<String, Object>, ApiGatewayResponse> {
private static final Logger LOG = Logger.getLogger(GetStatusHandler.class);
@SuppressWarnings("unchecked")
public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) {
BasicConfigurator.configure();
LOG.info("received: " + input);
try {
Map<String, String> pathParameters = (Map<String, String>) input.get("queryStringParameters");
if(pathParameters == null) {
LOG.info("Getting details for all persons ");
PersonControl control = new PersonControl();
Person[] result = control.myGetHandler(context);
return ApiGatewayResponse.builder()
.setStatusCode(200)
.setObjectBody(result)
.setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
.build();
}else {
String name = pathParameters.get("name");
LOG.info("Getting details for "+name);
PersonControl control = new PersonControl();
Person result = control.myGetHandler(name, context);
return ApiGatewayResponse.builder()
.setStatusCode(200)
.setObjectBody(result)
.setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
.build();
}
}catch(Exception e) {
LOG.error(e, e);
Response responseBody = new Response("Failure getting person", null);
return ApiGatewayResponse.builder()
.setStatusCode(500)
.setObjectBody(responseBody)
.setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
.build();
}
}
}
并不是说当返回 ApiGatewayResponse(通过构建器)时,对象只是传递给 .setObjectBody 方法 ('result'),无服务器自动为我们转换为 JSON。而已!代码中不需要解析为 JSON。
响应可以是用户定义的对象,如下所示
class Handler implements RequestHandler<SQSEvent, CustomObject> {
public CustomObject handleRequest(SQSEvent event, Context context) {
return new CustomObject();
}
}
可以找到示例代码 here。