{"id":2154,"date":"2023-04-02T13:27:19","date_gmt":"2023-04-02T05:27:19","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=2154"},"modified":"2024-01-10T22:05:17","modified_gmt":"2024-01-10T14:05:17","slug":"backend-system-receives-json-request-parameters-that-are-compatible-with-array-and-individual-object","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/04\/02\/backend-system-receives-json-request-parameters-that-are-compatible-with-array-and-individual-object\/","title":{"rendered":"\u540e\u53f0\u63a5\u6536json\u8bf7\u6c42\u53c2\u6570\u517c\u5bb9\u6570\u7ec4\u548c\u5355\u4e2a\u5bf9\u8c61"},"content":{"rendered":"<h2>\u80cc\u666f<\/h2>\n<p>\u573a\u666f\u4e00\uff1a\u524d\u540e\u7aef\u5bf9\u63a5\u63a5\u53e3\uff0c\u589e\u5220\u6539\u67e5\uff0c\u4e00\u5f00\u59cb\u8bf7\u6c42\u7684\u53c2\u6570\uff0c\u57fa\u672c\u662f\u5355\u6761\u6570\u636e\uff0cjson\u683c\u5f0f\u57fa\u672c\u662f<code>{&quot;key&quot;:&quot;value&quot;}<\/code>\uff0c\u4ea7\u54c1\u540e\u7eed\u6269\u5c55\uff0c\u4f20\u53c2\u53d8\u6210\u6279\u91cf\u64cd\u4f5cjson\u683c\u5f0f\u4e3a<code>[xxx,xxx]<\/code>\u6216\u8005<code>[{&quot;key&quot;:&quot;value&quot;}]<\/code>\uff0c\u6b64\u65f6\u540e\u7aef\u4fee\u6539\u539f\u63a5\u53e3\u7684\u63a5\u6536\u5bf9\u8c61\u4e3a\u6570\u7ec4\u7684\u8bdd\uff0c\u524d\u540e\u7aef\u7070\u5ea6\u53d1\u5e03\uff0c\u5c31\u4f1a\u5b58\u5728\u65e7\u7248\u672c\u4e0d\u517c\u5bb9<\/p>\n<p>\u573a\u666f\u4e8c\uff1a\u4ea7\u54c1\u7684\u5ba2\u6237\u7aef\uff0c\u53ef\u80fd\u7531web\u7aef\uff0cPC\u7aef\uff0cApp\u7aef\u7ec4\u6210\uff0c\u4f8b\u5982\u5f53\u67d0\u4e2a\u63a5\u53e3\u7684\u53c2\u6570\u7ed3\u6784\u6539\u9020\u4e3a\u6570\u7ec4\u65f6\uff0cweb\u7aef\u66f4\u65b0\u4e86\uff0c\u800cApp\u548cPC\u7aef\u672a\u66f4\u65b0\uff0c\u5c31\u5b58\u5728\u4e0d\u517c\u5bb9\u5176\u4ed6\u7aef<\/p>\n<p><!-- more --><\/p>\n<h2>\u89e3\u51b3\u601d\u8def<\/h2>\n<p>\uff081\uff09\u65b0\u589e\u63a5\u53e3<\/p>\n<ul>\n<li>\u4f18\u70b9\uff1a\u4e0d\u5f71\u54cd\u65e7\u63a5\u53e3\uff0c\u5f71\u54cd\u8303\u56f4\u5c0f<\/li>\n<li>\u7f3a\u70b9\uff1a\u91cd\u590d\u7684\u4ee3\u7801\uff0c\u540e\u671f\u5b58\u5728\u65e0\u7528\u7684\u63a5\u53e3<\/li>\n<\/ul>\n<p>\uff082\uff09\u524d\u540e\u7aef\u4e00\u5f00\u59cb\u7ea6\u5b9a\u6570\u7ec4\u7684\u8bf7\u6c42\u53c2\u6570<\/p>\n<ul>\n<li>\u4f18\u70b9\uff1a\u6bd4\u8f83\u6839\u672c\u89e3\u51b3\u95ee\u9898<\/li>\n<li>\u7f3a\u70b9\uff1a\u7a0b\u5e8f\u5458\u7684\u7f3a\u70b9\uff0c\u4e0d\u662f\u6240\u6709\u7a0b\u5e8f\u5458\u90fd\u80fd\u9884\u5148\u5224\u65ad\u63a5\u53e3\u53c2\u6570\u7684\u7c7b\u578b<\/li>\n<\/ul>\n<p>\uff083\uff09\u7edd\u5927\u591a\u6570\u60c5\u51b5\u662f\u9047\u5230\u95ee\u9898\u89e3\u51b3\u95ee\u9898\uff0c\u601d\u8def\u662f\u540e\u7aef\u62e6\u622a\u5904\u7406\u63a5\u6536\u7684\u8bf7\u6c42\u53c2\u6570\uff0c\u6821\u9a8c\u6b63\u786e\u540e\uff0c\u7edf\u4e00\u5c06json\u6570\u636e\u5c01\u88c5\u4e3a\u4e00\u4e2a\u901a\u7528\u5bf9\u8c61\u6216\u8005\u6570\u7ec4<\/p>\n<ul>\n<li>\u4f18\u70b9\uff1a\u53ea\u9700\u91cd\u6784\u539f\u5148\u7684\u63a5\u53e3\u5373\u53ef\u517c\u5bb9\u4e24\u79cd\u60c5\u51b5<\/li>\n<li>\u7f3a\u70b9\uff1a\u9700\u8981\u81ea\u5b9a\u4e49json\u7684\u89e3\u6790\uff0c\u89e3\u6790\u4e0d\u597d\u4f1a\u62a5json\u53cd\u5e8f\u5316\u5931\u8d25<\/li>\n<\/ul>\n<h2>\u4ee3\u7801\u5b9e\u73b0<\/h2>\n<h3>\u4ee5\u4e0b\u662f\u5c1d\u8bd5\u7528\u4e09\u79cd\u65b9\u6cd5\u89e3\u51b3\u4ee5\u4e0a\u573a\u666f\u7684\u8fc7\u7a0b<\/h3>\n<p>\u5b9a\u4e49\u4e00\u4e2a\u63a5\u6536\u524d\u7aef\u7684\u5b9e\u4f53\u7c7bMyBeanVo<\/p>\n<pre><code class=\"language-java\">public class MyBeanVo {\n    String value = \"\";\n\n    public String getValue() {\n        return value;\n    }\n\n    public void setValue(String value) {\n        this.value = value;\n    }\n}<\/code><\/pre>\n<h3>\u53ef\u53d8\u53c2\u6570\uff08\u4e0d\u80fd\u89e3\u51b3\uff09<\/h3>\n<p>\u5f00\u59cb\u4ee5\u4e3aJava\u4e2d\u7684\u53ef\u53d8\u53c2\u6570<code>Object...<\/code>\uff0c\u5728\u8c03\u7528\u65b9\u6cd5\u65f6\uff0c\u65e2\u53ef\u4ee5\u4f20\u5355\u4e2a\u53c2\u6570\uff0c\u53c8\u53ef\u4ee5\u4f20\u591a\u4e2a\u53c2\u6570\uff0c\u4f46\u662f\u4e0d\u80fd\u89e3\u51b3\u3002\u56e0\u4e3a\u53ef\u53d8\u53c2\u6570\u5b9e\u9645\u4e0a\u662f<code>Object[]<\/code>\u6570\u7ec4<\/p>\n<pre><code class=\"language-java\">@RestController\npublic class MyController {\n\n    @PostMapping(\"\/hello\")\n    public String test(@RequestBody MyBeanVo... param) {\n        MyBeanVo vo = param[0];\n        return vo.getValue();\n    }\n}<\/code><\/pre>\n<p>\u4f20\u5355\u4e2a\u53c2\u6570\u65f6\u62a5\u9519\uff1a<\/p>\n<pre><code class=\"language-java\">\"exception\":\"org.springframework.http.converter.HttpMessageNotReadableException\",\"message\":\"JSON parse error: Can not deserialize instance of com.test.config.MyBean[] out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.test.config.MyBean[] out of START_OBJECT token\\n at [Source: java.io.PushbackInputStream@24e6f1b2; line: 1, column: 1]\"<\/code><\/pre>\n<p>\u539f\u56e0\uff1a\u524d\u7aef\u7684\u53c2\u6570(\u5355\u4e2a\u6570\u636e)\u65e0\u6cd5\u89e3\u6790\u4e3a<code>MyBean[]<\/code>\uff0c\u800c\u8fd9\u6d89\u53ca\u5230\u4e86Json\u7684\u53cd\u5e8f\u5217\u5316<\/p>\n<h3>\u81ea\u5b9a\u4e49\u53cd\u5e8f\u5217\u5316<\/h3>\n<h4>\u65b9\u6848\u4e00<\/h4>\n<p>\u5b9a\u4e49\u4e00\u4e2a\u6279\u91cf\u5b9e\u4f53\u7c7b<\/p>\n<pre><code class=\"language-java\">import java.util.List;\n\npublic class BatchVo<T> {\n    List<T> list;\n\n    public List<T> getList() {\n        return list;\n    }\n\n    public void setList(List<T> list) {\n        this.list = list;\n    }\n}<\/code><\/pre>\n<p><code>@JsonComponent<\/code>\u6ce8\u89e3\u4f1a\u81ea\u52a8\u6ce8\u5165\u5230spring\u4e2d\uff0c\u53cd\u5e8f\u5217\u5316<code>BatchVo&lt;MyBeanVo&gt;<\/code>\u65f6\u4f1a\u81ea\u52a8\u6267\u884c<code>deserialize<\/code>\u65b9\u6cd5\uff0c\u4f46\u662f\u6709\u4e2a\u5f0a\u7aef\uff0c<code>JsonDeserializer&lt;T&gt;<\/code>\u7684<code>T<\/code>\u5fc5\u987b\u662f\u5177\u4f53\u7c7b\u578b\uff0c\u4e0d\u80fd\u643a\u5e26\u6cdb\u578b\uff0c\u4e0d\u540c\u53c2\u6570\u5c31\u6709\u4e0d\u540c\u7684Vo\uff0c\u8981\u9488\u5bf9\u4e0d\u540c\u7684Vo\u90fd\u5199\u4e00\u4e2a\u81ea\u5b9a\u4e49\u53cd\u5e8f\u5316\u7684\u7c7b\u5c31\u5f88\u9ebb\u70e6<\/p>\n<pre><code class=\"language-java\">import com.alibaba.fastjson.JSONObject;\nimport com.fasterxml.jackson.core.JsonParser;\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.core.TreeNode;\nimport com.fasterxml.jackson.databind.DeserializationContext;\nimport com.fasterxml.jackson.databind.JsonDeserializer;\nimport org.springframework.boot.jackson.JsonComponent;\nimport java.io.IOException;\nimport java.util.ArrayList;\n\n@JsonComponent\npublic class MyJsonDeserializer extends JsonDeserializer<BatchVo<MyBeanVo>> {\n    @Override\n    public BatchVo<MyBeanVo> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {\n        TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);\n        BatchVo vo = new BatchVo<MyBeanVo>();\n        String str = treeNode.toString();\n        \/\/ \u524d\u7aef\u4f20\u53c2\u662f\u6570\u7ec4\n        if (treeNode.isArray()) {\n            vo.list = JSONObject.parseArray(str, MyBeanVo.class);\n        }\n        \/\/ \u524d\u7aef\u4f20\u53c2\u662f\u5355\u4e2a\u6570\u636e\n        if (treeNode.isObject()) {\n            vo.list = new ArrayList();\n            vo.list.add(JSONObject.parseObject(str, MyBeanVo.class));\n        }\n        return vo;\n    }\n}<\/code><\/pre>\n<p>\u7ed1\u5b9a\u7684\u53c2\u6570\u5fc5\u987b\u52a0<code>@RequestBody<\/code>\uff0c\u4e0d\u7136\u53cd\u5e8f\u5217\u5316\u65e0\u6cd5\u8d70<code>MyJsonDeserializer<\/code>\u7684<code>deserialize<\/code>\u65b9\u6cd5<\/p>\n<pre><code class=\"language-java\">@RestController\npublic class MyController {\n\n    @PostMapping(\"\/hello\")\n    public String test(@RequestBody BatchVo<MyBeanVo> param) {\n        MyBeanVo vo = param.getList().get(0);\n        return vo.getValue();\n    }\n}<\/code><\/pre>\n<ul>\n<li>\u53d1\u8d77\u8bf7\u6c42\uff1a<code>POST localhost:8080\/hello<\/code><\/li>\n<li>body\u53c2\u6570\uff1a<code>[{&quot;value&quot;:&quot;hello world&quot;}]<\/code> \u6216\u8005 <code>{&quot;value&quot;:&quot;hello world&quot;}<\/code><\/li>\n<li>\u8fd4\u56de\u7686\u4e3a\uff1a<code>hello world<\/code><\/li>\n<\/ul>\n<p>\u5206\u6790\uff1a\u660e\u663e\u8fd9\u79cd\u8bbe\u8ba1\u9664\u975eMyBean\u53ef\u4ee5\u8bbe\u8ba1\u5f97\u5f88\u5f3a\u5927\u3001\u5f88\u901a\u7528\uff0c\u53ef\u4ee5\u63a5\u6536\u524d\u7aef\u6240\u6709\u7684\u8bf7\u6c42\u53c2\u6570\u3002\u8981\u4e0d\u7136\u6bcf\u4e2aVo\u7c7b\u90fd\u9700\u8981\u5199\u4e00\u4e2a\u5b9e\u73b0<code>JsonDeserializer<\/code>\u7684\u53cd\u5e8f\u5316\u5217\u89e3\u6790\u7c7b\uff0c\u6216\u8005\u6bcf\u6b21\u90fd\u9700\u8981\u5728contrller\u5c42\u505aJson\u7684\u518d\u6b21\u53cd\u5e8f\u5217\u5316\u3002\u8fd9\u6837\u7684\u5b9e\u73b0\u53d8\u5f97\u7e41\u7410\uff0c\u589e\u52a0\u4ee3\u7801\u91cf<\/p>\n<h4>\u65b9\u6848\u4e8c<\/h4>\n<p>\u81ea\u5b9a\u4e49\u53c2\u6570\u89e3\u6790\u5668<\/p>\n<pre><code class=\"language-java\">import com.alibaba.fastjson.JSON;\nimport org.apache.commons.io.IOUtils;\nimport org.springframework.core.MethodParameter;\nimport org.springframework.web.bind.support.WebDataBinderFactory;\nimport org.springframework.web.context.request.NativeWebRequest;\nimport org.springframework.web.method.support.HandlerMethodArgumentResolver;\nimport org.springframework.web.method.support.ModelAndViewContainer;\n\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.List;\n\npublic class RequestBodyArgumentResolver implements HandlerMethodArgumentResolver {\n\n    \/**\n     * \u53ea\u62e6\u622aBatchBody\u6ce8\u89e3\u4e14\u4e3a\u6570\u7ec4\u7684\u8bf7\u6c42\u53c2\u6570\n     * \u6bcf\u4e2amapping\u7684\u65b9\u6cd5\u53ea\u4f1a\u6267\u884c\u4e00\u6b21\u6b64\u65b9\u6cd5\n     *\/\n    public boolean supportsParameter(MethodParameter methodParameter) {\n        Class paramType = methodParameter.getParameterType();\n        boolean isArray = paramType.isArray();\n        boolean isList = paramType.isAssignableFrom(List.class);\n        boolean hasAnnotation = methodParameter.hasParameterAnnotation(BatchBody.class);\n        return hasAnnotation && (isArray || isList);\n    }\n\n    \/**\n     * \u901a\u8fc7\u4e86supportsParameter\u6821\u9a8c\u7684mapping\u65b9\u6cd5\u6bcf\u6b21\u90fd\u4f1a\u6267\u884c\u6b64\u65b9\u6cd5\n     *\/\n    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {\n        String json = getRequestBodyString(nativeWebRequest);\n        Type type = methodParameter.getGenericParameterType();\n        Object obj = JSON.parseObject(json, type);\n        return obj;\n    }\n\n    \/**\n     * \u683c\u5f0f\u5316json\u6570\u636e\uff0c\u7edf\u4e00\u4e3a\u6570\u7ec4\u5f62\u5f0f\n     * \u89e3\u6790json\u5b57\u7b26\u4e32\u9700\u505a\u5f97\u66f4\u5b8c\u5584\uff0c\u4f8b\u5982\u6821\u9a8cjson\u683c\u5f0f\u662f\u5426\u6b63\u786e\n     *\/\n    private String getRequestBodyString(NativeWebRequest webRequest) throws IOException {\n        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);\n        String json = IOUtils.toString(request.getInputStream(), \"UTF-8\").trim();\n        if (json.startsWith(\"{\") && json.endsWith(\"}\")) {\n            return \"[\" + json + \"]\";\n        }\n        if (json.startsWith(\"[\") && json.endsWith(\"]\")) {\n            return json;\n        }\n        return null;\n    }\n}<\/code><\/pre>\n<p>\u5c06<code>RequestBodyArgumentResolver<\/code>\u6ce8\u518c\u5230<code>WebMvcConfigurerAdapter<\/code>\u5f53\u4e2d\u3002<\/p>\n<pre><code class=\"language-java\">import org.springframework.context.annotation.Configuration;\nimport org.springframework.web.method.support.HandlerMethodArgumentResolver;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;\nimport java.util.List;\n\n@Configuration\npublic class WebConfig extends WebMvcConfigurerAdapter {\n    @Override\n    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {\n        argumentResolvers.add(new RequestBodyArgumentResolver());\n        super.addArgumentResolvers(argumentResolvers);\n    }\n}<\/code><\/pre>\n<p>\u5b9a\u4e49mapping\u63a5\u53e3\uff0c\u5728\u53c2\u6570\u4e0a\u52a0\u4e0a\u6ce8\u89e3<code>@BatchBody<\/code><\/p>\n<pre><code class=\"language-java\">@RestController\npublic class MyController {\n\n    @PostMapping(\"\/hello2\")\n    public String test2(@BatchBody MyBeanVo[] param) {\n        MyBeanVo vo = param[0];\n        return vo.getValue();\n    }\n\n    @PostMapping(\"\/hello3\")\n    public String test3(@BatchBody List<MyBeanVo> param) {\n        MyBeanVo vo = param.get(0);\n        return vo.getValue();\n    }\n\n    @PostMapping(\"\/hello4\")\n    public String test4(@BatchBody MyBeanVo... param) {\n        MyBeanVo vo = param[0];\n        return vo.getValue();\n    }\n}<\/code><\/pre>\n<ul>\n<li>\u4f20\u5165\u53c2\u6570<code>{&quot;value&quot;:&quot;hello world&quot;}<\/code>\u6216\u8005<code>[{&quot;value&quot;:&quot;hello world&quot;}]<\/code><\/li>\n<li>\u8fd4\u56de\u7686\u4e3a\uff1a<code>hello world<\/code><\/li>\n<\/ul>\n<p>\u53ef\u4ee5\u5b8c\u7f8e\u517c\u5bb9\u6570\u7ec4\uff0c\u96c6\u5408\uff0c\u53ef\u53d8\u53c2\u6570(\u5b9e\u9645\u662f\u6570\u7ec4)<\/p>\n<p>\u5206\u6790\uff1a<code>RequestBodyArgumentResolver<\/code>\u89e3\u6790Json\u5b57\u7b26\u4e32\uff0c\u9700\u8981\u68c0\u6d4b\u683c\u5f0f\u662f\u5426\u6b63\u786e\uff0c\u9700\u8981\u517c\u5bb9\u5355\u4e2a\u6570\u636e\u548c\u6279\u91cf\u6570\u636e\u7684\u53c2\u6570\uff0c\u53ea\u9700\u8981\u628a\u8be5\u53c2\u6570\u6539\u6210List\/\u6570\u7ec4[]\/\u53ef\u53d8\u53c2\u6570\uff0c\u518d\u5728\u524d\u9762\u52a0\u4e0a<code>@BatchBody<\/code>\u6ce8\u89e3\u5373\u53ef\u5b9e\u73b0\uff0cservice\u5c42\u548cdao\u5c42\u8981\u8bbe\u8ba1\u4e3a\u6279\u91cf\u7684\u4f20\u53c2<\/p>\n<h2>\u603b\u7ed3<\/h2>\n<p>SpringMVC\u63d0\u4f9b\u4e86\u5f88\u591a\u81ea\u5b9a\u4e49\u62e6\u622a\/\u8fc7\u6ee4\u5668\u7684\u63a5\u53e3\u548c\u7c7b\uff0c\u6ce8\u518c\u5230\u914d\u7f6e\u7c7b\u4e2d\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u65b9\u4fbf\u7684api\uff0c\u80fd\u6ee1\u8db3\u5f00\u53d1\u4e2d\u7684\u5927\u591a\u6570\u573a\u666f\u7684\u9700\u6c42\uff0c\u5176\u6269\u5c55\u6027\u771f\u7684\u505a\u5f97\u5f88\u8d5e\u3002\u540c\u65f6\uff0c\u6211\u4eec\u5728\u8bbe\u8ba1\u4e00\u4e2a\u63a5\u53e3\uff0c\u4e00\u4e2a\u51fd\u6570\uff0c\u591a\u8003\u8651\u5176\u6269\u5c55\u548c\u63a5\u5165\u573a\u666f\uff0c\u8ba9\u6bcf\u4e2a\u51fd\u6570\u53d8\u5f97\u66f4\u5065\u58ee\uff0c\u5148\u8bbe\u8ba1\u518d\u7f16\u7801\uff0c\u51cf\u5c11\u8bd5\u9519\u7684\u6210\u672c<\/p>\n<blockquote>\n<p>\u8f6c\u8f7d\u81f3\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/juejin.cn\/post\/6844903745059307527\">https:\/\/juejin.cn\/post\/6844903745059307527<\/a><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>\u80cc\u666f \u573a\u666f\u4e00\uff1a\u524d\u540e\u7aef\u5bf9\u63a5\u63a5\u53e3\uff0c\u589e\u5220\u6539\u67e5\uff0c\u4e00\u5f00\u59cb\u8bf7\u6c42\u7684\u53c2\u6570\uff0c\u57fa\u672c\u662f\u5355\u6761\u6570\u636e\uff0cjson\u683c\u5f0f\u57fa\u672c\u662f{&quot;ke [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43],"tags":[74],"class_list":["post-2154","post","type-post","status-publish","format-standard","hentry","category-java-basic","tag-json"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/2154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=2154"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/2154\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=2154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=2154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=2154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}