将 JSON 发布到 REST API [英] Posting JSON to REST API

查看:29
本文介绍了将 JSON 发布到 REST API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个接受 JSON 请求的 REST API.

我正在使用 CURL 对其进行测试:

curl -i -POST -H 'Accept: application/json' -d '{"id":1,"pan":11111}' http://localhost:8080/PurchaseAPIServer/api/purchase


但是出现以下错误:

HTTP/1.1 415 不支持的媒体类型服务器:Apache-Coyote/1.1内容类型:文本/html;字符集=utf-8内容长度:1051日期:2012 年 4 月 25 日,星期三 21:36:14 GMT服务器拒绝此请求,因为请求实体的格式不为所请求方法的请求资源所支持 ().



在调试时,它甚至从未进入我在控制器中的创建操作.

import java.util.List;导入 org.springframework.beans.factory.annotation.Autowired;导入 org.springframework.http.HttpStatus;导入 org.springframework.stereotype.Controller;导入 org.springframework.web.bind.annotation.PathVariable;导入 org.springframework.web.bind.annotation.RequestBody;导入 org.springframework.web.bind.annotation.RequestMapping;导入 org.springframework.web.bind.annotation.RequestMethod;导入 org.springframework.web.bind.annotation.ResponseBody;导入 org.springframework.web.bind.annotation.ResponseStatus;导入 com.app.model.Purchase;导入 com.app.service.IPurchaseService;@控制器公共类购买控制器{@自动连线私人IP购买服务购买服务;@RequestMapping(value = "purchase", method = RequestMethod.GET)@ResponseBody公开最终清单<购买>得到所有() {返回 purchaseService.getAll();}@RequestMapping(value = "purchase", method = RequestMethod.POST)@ResponseStatus( HttpStatus.CREATED )public void create(@RequestBody final Purchase entity) {purchaseService.addPurchase(实体);}}



更新

我在 AppConfig.java 中添加了 Jackson 配置:

@Configuration@ComponentScan(basePackages = "com.app")公共类 AppConfig {@豆角,扁豆公共 AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter(){final AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter = new AnnotationMethodHandlerAdapter();最终 MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter();HttpMessageConverter[] httpMessageConverter = { mappingJacksonHttpMessageConverter };String[] supportedHttpMethods = { "POST", "GET", "HEAD" };annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverter);annotationMethodHandlerAdapter.setSupportedMethods(supportedHttpMethods);返回注解MethodHandlerAdapter;}}



我的 GET 现在可以正常工作了:

curl -i -H "Content-Type:application/json" -H "Accept:application/json" http://localhost:8080/PurchaseAPIServer/api/purchaseHTTP/1.1 200 正常服务器:Apache-Coyote/1.1内容类型:应用程序/json传输编码:分块日期:2012 年 4 月 26 日星期四 21:19:55 GMT[{"id":1,"pan":111}]



但是在尝试 POST 时我得到以下信息:

curl -i -X POST -H "Content-Type:application/json" -H "Accept:application/json" http://localhost:8080/PurchaseAPIServer/api/purchaseMe -d "{"id":2,"pan":122}"HTTP/1.1 400 错误请求服务器:Apache-Coyote/1.1内容类型:文本/html;字符集=utf-8内容长度:971日期:2012 年 4 月 26 日星期四 21:29:56 GMT连接:关闭客户端发送的请求在语法上不正确 ().



我的模型:

@Entity@XmlRootElement公共类购买实现可序列化{/****/私有静态最终长serialVersionUID = 6603477834338392140L;@ID@GeneratedValue(策略 = GenerationType.AUTO)私人长ID;私龙盘;公共长 getId() {返回标识;}公共无效setId(长id){this.id = id;}公共长 getPan() {回锅;}public void setPan(Long pan) {this.pan = 锅;}}



知道我哪里出错了吗?

谢谢

解决方案

正如 sdouglass 建议的那样,Spring MVC 会自动检测 Jackson并设置一个 MappingJacksonHttpMessageConverter 来处理与 JSON 的转换.但我确实需要明确配置转换器才能使其正常工作,正如他也指出的那样.

我添加了以下内容并且我的 CURL GET 请求正在工作......万岁.

AppConfig.java

@Configuration@ComponentScan(basePackages = "com.app")公共类 AppConfig {@豆角,扁豆公共 AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter(){final AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter = new AnnotationMethodHandlerAdapter();最终 MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter();HttpMessageConverter[] httpMessageConverter = { mappingJacksonHttpMessageConverter };String[] supportedHttpMethods = { "POST", "GET", "HEAD" };annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverter);annotationMethodHandlerAdapter.setSupportedMethods(supportedHttpMethods);返回注解MethodHandlerAdapter;}}


curl -i -H "Content-Type:application/json" -H "Accept:application/json" http://localhost:8080/PurchaseAPIServer/api/purchaseHTTP/1.1 200 正常服务器:Apache-Coyote/1.1内容类型:应用程序/json传输编码:分块日期:2012 年 4 月 26 日星期四 21:19:55 GMT[{"id":1,"pan":111}]



但是以下 CURL POST 仍然无法正常工作(从不点击控制器操作,也没有提供控制台调试信息.

curl -i -X POST -H "Content-Type:application/json" http://localhost:8080/PurchaseAPIServer/api/purchaseMe -d "{"id":2,"pan":122}"HTTP/1.1 400 错误请求服务器:Apache-Coyote/1.1内容类型:文本/html;字符集=utf-8内容长度:971日期:2012 年 4 月 26 日星期四 21:29:56 GMT连接:关闭客户端发送的请求在语法上不正确 ().



所以我添加了 Logback 以开始一些详细的调试.

<预><代码><配置><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><编码器><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</模式></编码器></appender><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>/home/thomas/springApps/purchaseapi.log</file><编码器><pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</模式></编码器></appender><logger name="org.hibernate" level="DEBUG"/><logger name="org.springframework" level="TRACE"/><logger name="org.springframework.transaction" level="INFO"/><logger name="org.springframework.security" level="INFO"/><!-- 调试安全相关问题(DEBUG)--><logger name="org.springframework.web.servlet.mvc" level="TRACE"/><!-- 一些序列化问题在跟踪级别:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod --><!-- 我们的服务--><logger name="com.app" level="DEBUG"/><!-- <logger name="com.app" level="INFO"/>--><!-- 如果正在执行安装程序则跟随--><root level="INFO"><appender-ref ref="文件"/></root></配置>



将 TRACE 级别的调试添加到 org.springframework.web.servlet.mvc 给了我问题的答案.

2012-04-28 14:17:44,579 DEBUG [http-bio-8080-exec-3] oswsmmaRequestResponseBodyMethodProcessor [AbstractMessageConverterMethodArgumentResolver.java:117] 阅读 [com.app.model.Purchase] 作为应用程序/json" 使用 [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@74a14fed]2012-04-28 14:17:44,604 TRACE [http-bio-8080-exec-3] o.s.w.s.m.m.a.ServletInvocableHandlerMethod [InvocableHandlerMethod.java:159] 解析参数时出错 [0] [type=com.app.model.Purchase]HandlerMethod详情:控制器 [com.app.controller.PurchaseController]方法[public void com.app.controller.PurchaseController.create(com.app.model.Purchase)]org.springframework.http.converter.HttpMessageNotReadableException:无法读取 JSON:意外字符('p'(代码 112)):期望双引号开始字段名称



我将我的 CURL POST 更改为以下所有内容:

curl -i -X POST -H "Content-Type:application/json" http://localhost:8080/PurchaseAPIServer/api/purchase -d '{"pan":11111}'HTTP/1.1 201 创建服务器:Apache-Coyote/1.1内容长度:0日期:2012 年 4 月 28 日星期六 13:19:40 GMT

希望有人觉得这很有用.

I'm creating a REST API that will accept JSON requests.

I'm testing it out using CURL:

curl -i -POST -H 'Accept: application/json' -d '{"id":1,"pan":11111}' http://localhost:8080/PurchaseAPIServer/api/purchase


But getting the following error:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 25 Apr 2012 21:36:14 GMT

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().



When debugging it never even gets into my create action in the controller.

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.app.model.Purchase;
import com.app.service.IPurchaseService;

@Controller
public class PurchaseController {

    @Autowired
    private IPurchaseService purchaseService;

    @RequestMapping(value = "purchase", method = RequestMethod.GET)
    @ResponseBody
    public final List<Purchase> getAll() {
        return purchaseService.getAll();
    }

    @RequestMapping(value = "purchase", method = RequestMethod.POST)
    @ResponseStatus( HttpStatus.CREATED )
    public void create(@RequestBody final Purchase entity) {
        purchaseService.addPurchase(entity);
    }
}



UPDATE

I added Jackson config to AppConfig.java:

@Configuration
@ComponentScan(basePackages = "com.app")
public class AppConfig {

    @Bean
    public AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter()
    {
        final AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter = new AnnotationMethodHandlerAdapter();
        final MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter();

        HttpMessageConverter<?>[] httpMessageConverter = { mappingJacksonHttpMessageConverter };

        String[] supportedHttpMethods = { "POST", "GET", "HEAD" };

        annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverter);
        annotationMethodHandlerAdapter.setSupportedMethods(supportedHttpMethods);

        return annotationMethodHandlerAdapter;
    }
}



My GETs are working correctly now:

curl -i -H "Content-Type:application/json" -H "Accept:application/json" http://localhost:8080/PurchaseAPIServer/api/purchase

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 26 Apr 2012 21:19:55 GMT

[{"id":1,"pan":111}]



But I get the following when attempting a POST:

curl -i -X POST -H "Content-Type:application/json" -H "Accept:application/json" http://localhost:8080/PurchaseAPIServer/api/purchaseMe -d "{"id":2,"pan":122}"

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 971
Date: Thu, 26 Apr 2012 21:29:56 GMT
Connection: close

The request sent by the client was syntactically incorrect ().



My Model:

@Entity
@XmlRootElement
public class Purchase implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 6603477834338392140L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private Long pan;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getPan() {
        return pan;
    }

    public void setPan(Long pan) {
        this.pan = pan;
    }

}



Any ideas where I'm going wrong?

Thanks

解决方案

As sdouglass suggested, Spring MVC automatically detects Jackson and sets up a MappingJacksonHttpMessageConverter to handle conversion to/from JSON. But I did need explicity configure the converter to get it to work as he also pointed out.

I added the following and my CURL GET requests were working..Hooray.

AppConfig.java

@Configuration
@ComponentScan(basePackages = "com.app")
public class AppConfig {

    @Bean
    public AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter()
    {
        final AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter = new AnnotationMethodHandlerAdapter();
        final MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter();

        HttpMessageConverter<?>[] httpMessageConverter = { mappingJacksonHttpMessageConverter };

        String[] supportedHttpMethods = { "POST", "GET", "HEAD" };

        annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverter);
        annotationMethodHandlerAdapter.setSupportedMethods(supportedHttpMethods);

        return annotationMethodHandlerAdapter;
    }
}


curl -i -H "Content-Type:application/json" -H "Accept:application/json" http://localhost:8080/PurchaseAPIServer/api/purchase

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 26 Apr 2012 21:19:55 GMT

[{"id":1,"pan":111}]



But the following CURL POST was still not working (Never hitting the controller action and giving no console debug info.

curl -i -X POST -H "Content-Type:application/json"  http://localhost:8080/PurchaseAPIServer/api/purchaseMe -d "{"id":2,"pan":122}"

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 971
Date: Thu, 26 Apr 2012 21:29:56 GMT
Connection: close

The request sent by the client was syntactically incorrect ().



So I added Logback to get some detailed debugging started.

<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>/home/thomas/springApps/purchaseapi.log</file>
        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n
            </pattern>
        </encoder>
    </appender>

    <logger name="org.hibernate" level="DEBUG" />

    <logger name="org.springframework" level="TRACE" />
    <logger name="org.springframework.transaction" level="INFO" />
    <logger name="org.springframework.security" level="INFO" /> <!-- to debug security related issues (DEBUG) -->
    <logger name="org.springframework.web.servlet.mvc" level="TRACE" /> <!-- some serialization issues are at trace level here: org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod -->

    <!-- our service -->
    <logger name="com.app" level="DEBUG" />
    <!-- <logger name="com.app" level="INFO" /> --><!-- to follow if setup is being executed -->

    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>

</configuration>



Adding TRACE level debugging to org.springframework.web.servlet.mvc gave me the answer to the problem.

2012-04-28 14:17:44,579 DEBUG [http-bio-8080-exec-3] o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor [AbstractMessageConverterMethodArgumentResolver.java:117] Reading [com.app.model.Purchase] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@74a14fed]
2012-04-28 14:17:44,604 TRACE [http-bio-8080-exec-3] o.s.w.s.m.m.a.ServletInvocableHandlerMethod [InvocableHandlerMethod.java:159] Error resolving argument [0] [type=com.app.model.Purchase]
HandlerMethod details: 
Controller [com.app.controller.PurchaseController]
Method [public void com.app.controller.PurchaseController.create(com.app.model.Purchase)]

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unexpected character ('p' (code 112)): was expecting double-quote to start field name



I changed my CURL POSTs to the following an it all worked:

curl -i -X POST -H "Content-Type:application/json" http://localhost:8080/PurchaseAPIServer/api/purchase -d '{"pan":11111}'
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Content-Length: 0
Date: Sat, 28 Apr 2012 13:19:40 GMT

Hopefully someone finds this useful.

这篇关于将 JSON 发布到 REST API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆