我正在创建一个REST API,它将接受JSON请求。
我正在使用CURL进行测试:
curl -i -POST -H 'Accept: application/json' -d '{"id":1,"pan":11111}' http://localhost:8080/PurchaseAPIServer/api/purchase
但是出现以下错误:
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 ().
调试时,它甚至都不会进入控制器中的create动作。
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); } }
我将Jackson配置添加到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 -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}]
但是尝试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 ().
我的模特:
@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; } }
有什么想法我要去哪里吗?
谢谢
正如sdouglass所建议的那样,SpringMVC自动检测杰克逊并设置一个MappingJacksonHttpMessageConverter来处理与JSON的转换。但是我确实需要明确配置转换器以使其正常工作,正如他还指出的那样。
我添加了以下内容,并且我的CURL GET请求正在工作..万岁。
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}]
但是以下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 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 ().
因此,我添加了Logback来开始一些详细的调试。
<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>
在 org.springframework.web.servlet.mvc中 添加TRACE级别的调试,为我提供了解决问题的方法。
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
我将CURL POST更改为以下所有内容:
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
希望有人觉得这很有用。