我有一个Spring REST服务(用Groovy编写;尽管没关系),它公开了一个安全的端点,如下所示:
class AppData { String id String payload String fizzbuzz } @RequestMapping(method=RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) @ResponseBody AppResponse onAppData(@RequestBody AppData appData) { // Does some processing on appData and then saves // its 'payload' field to a MongoDB }
当它收到以下形式的JSON时,这工作得很好:
{ "id" : "12345", "payload" : "Please save me to a MongoDB", "fizzbuzz" : "wakka wakka" }
我在这里使用Jackson来处理JSON序列化。
问题是我现在希望该payload属性为true JSON,而不是String。所以我希望能够向端点发送如下内容:
payload
{ "id" : "12345", "payload" : { "foo" : 24, "bar" : false, "whistlefeather" : "Yes of course" }, "fizzbuzz" : "wakka wakka" }
并将有效负载正确保存到MongoDB。但是这里有个陷阱:
许多不同的团队(可能有数百个)将发送此终结点AppData,并且它们的所有负载看起来都将完全不同(每个团队都希望将其发送给我并保存在MongoDB中的负载不同)。而且我不想为我AppData加入的每个新团队编写一个新的终结点和子类(因此可以将此终结点暴露给它)。
AppData
有什么办法可以:
AppData#payload
如果我发送的JSON消息payload也是JSON(并且不是字符串),则按原样保留我的代码,Spring只会返回400且响应主体为空。发生这种情况是因为Spring期望payload是一个String,但是看到它是一个JSON对象。
关于我可以在AppData课堂上做什么以解决此问题的任何想法,或关于最佳实践的任何想法?
使用JsonNode作为有效负载的类型:
public class AppData { String id; JsonNode payload; String fizzbuzz; public String getId() { return id; } public void setId(String id) { this.id = id; } public JsonNode getPayload() { return payload; } public void setPayload(JsonNode payload) { this.payload = payload; } public String getFizzbuzz() { return fizzbuzz; } public void setFizzbuzz(String fizzbuzz) { this.fizzbuzz = fizzbuzz; } public static void main(String[] args) throws IOException { String json = "{\n" + " \"id\" : \"12345\",\n" + " \"payload\" : {\n" + " \"foo\" : 24,\n" + " \"bar\" : false,\n" + " \"whistlefeather\" : \"Yes of course\"\n" + " },\n" + " \"fizzbuzz\" : \"wakka wakka\"\n" + "}"; ObjectMapper om = new ObjectMapper(); AppData appData = om.readValue(json, AppData.class); System.out.println("appData ID = " + appData.getId()); System.out.println("appData fizzbuzz = " + appData.getFizzbuzz()); System.out.println("appData payload = " + appData.getPayload()); String json2 = "{\n" + " \"id\" : \"12345\",\n" + " \"payload\" : \"Please save me to a MongoDB\",\n" + " \"fizzbuzz\" : \"wakka wakka\"\n" + "}"; appData = om.readValue(json2, AppData.class); System.out.println("appData ID = " + appData.getId()); System.out.println("appData fizzbuzz = " + appData.getFizzbuzz()); System.out.println("appData payload = " + appData.getPayload()); } }
输出:
appData ID = 12345 appData fizzbuzz = wakka wakka appData payload = {"foo":24,"bar":false,"whistlefeather":"Yes of course"} appData ID = 12345 appData fizzbuzz = wakka wakka appData payload = "Please save me to a MongoDB"
请注意,要获取有效负载的JSON字符串,您不应使用上例中的toString()。您应该使用objectMapper.writeValueAsString(payload)。
objectMapper.writeValueAsString(payload)