将 JSON 发布到 REST API [英] Posting JSON to 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 以开始一些详细的调试.
将 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屋!