问题描述
我正在创建一个接受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
Content- :text / html; charset = utf-8
Content-Length:1051
日期:Wed,25 Apr 2012 21:36:14 GMT
服务器拒绝了此请求,因为请求实体处于被请求的方法()的所请求的资源不支持的格式。
调试时,
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购买实体){
purchaseService.addPurchase(entity);
}
}
UPDATE
我添加了Jackson config到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;
}
}
我的GET现在正常工作:
curl -i -HContent-Type:application / json-HAccept :application / jsonhttp:// localhost:8080 / PurchaseAPIServer / api / purchase
HTTP / 1.1 200 OK
服务器:Apache-Coyote / 1.1
Content- application / json
Transfer-Encoding:chunked
Date:Thu,26 Apr 2012 21:19:55 GMT
[{id:1,pan:111 }]
但是, a POST:
curl -i -X POST -HContent-Type:application / json-HAccept:application / jsonhttp:// localhost:8080 / PurchaseAPIServer / api / purchaseMe -d{id:2,pan:122}
HTTP / 1.1 400错误请求
服务器:Apache-Coyote / 1.1
Content-Type:text / html; charset = utf-8
Content-Length:971
Date:Thu,26 Apr 2012 21:29:56 GMT
连接:close
客户端发送的请求在语法上不正确()。
我的模型:
@Entity
@XmlRootElement
public class Purchase implements Serializable {
/ **
*
* /
private static final long serialVersionUID = 6603477834338392140L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
私人长盘
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;
}
}
任何想法我会出错?
感谢
由于建议,Spring MVC会自动检测Jackson并设置MappingJacksonHttpMessageConverter以处理从/到JSON的转换。但我需要显式配置转换器,让它工作,他也指出了。
我添加了以下和我的CURL GET请求正在工作。 / p>
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 -HContent-Type:application / json-HAccept:application / jsonhttp:// localhost:8080 / PurchaseAPIServer / api / purchase
pre>
HTTP / 1.1 200 OK
服务器:Apache-Coyote / 1.1
Content-Type:application / json
传输编码:chunked
日期:Thu,26 Apr 2012 21:19:55 GMT
[{id:1,pan:111}]
但是下面的CURL POST仍然不能正常工作(从不执行控制器操作,并且不提供控制台调试信息。curl -i -X POST -HContent-Type:application / jsonhttp:// localhost:8080 / PurchaseAPIServer / api / purchaseMe -d{id:2,pan:122}
HTTP / 1.1 400错误请求
服务器: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
客户端发送的请求语法不正确()。
所以我添加了以获取一些详细的调试开始。
< appender name =STDOUTclass =ch.qos.logback.core.ConsoleAppender>
< encoder>
< pattern>%d {HH:mm:ss.SSS} [%thread]%-5级别%logger {36} - %msg%n
< / pattern>
< / encoder>
< / appender>
< appender name =FILEclass =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.hibernatelevel =DEBUG/>
< logger name =org.springframeworklevel =TRACE/>
< logger name =org.springframework.transactionlevel =INFO/>
< logger name =org.springframework.securitylevel =INFO/> <! - 调试安全相关的问题(DEBUG) - >
< logger name =org.springframework.web.servlet.mvclevel =TRACE/> <! - 一些序列化问题在这里是跟踪级别:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod - >
<! - 我们的服务 - >
< logger name =com.applevel =DEBUG/>
<! - < logger name =com.applevel =INFO/> - ><! - 如果设置正在执行则跟随 - >
< root level =INFO>
< appender-ref ref =FILE/>
< / root>
< / configuration>
将TRACE级别调试添加到 org .springframework.web.servlet.mvc 给了我这个问题的答案。2012-04-28 14 :17:44,579 DEBUG [http-bio-8080-exec-3] oswsmmaRequestResponseBodyMethodProcessor [AbstractMessageConverterMethodArgumentResolver.java:117]使用[org.springframework.http.converter]读取[com.app.model.Purchase]为application / json .json.MappingJacksonHttpMessageConverter @ 74a14fed]
2012-04-28 14:17:44,604 TRACE [http-bio-8080-exec-3] oswsmmaServletInvocableHandlerMethod [InvocableHandlerMethod.java:159]解析参数时出错[0] [类型= com.app.model.Purchase]
HandlerMethod详细信息:
Controller [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 -HContent-Type:application / jsonhttp:// localhost:8080 / PurchaseAPIServer / api / purchase -d'{pan:11111}'
HTTP / 1.1 201创建
服务器:Apache-Coyote / 1.1
Content-Length:0
Date:Sat,28 Apr 2012 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!