我创建一个REST API将接受JSON请求。
我使用的卷曲测试它:
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 ().
当从未调试它甚至进入控制器我创建行动。
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
我说杰克逊配置到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}]
但我得到试图进行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;
}
}
任何想法,我要去哪里错了吗?
谢谢
Answer 1:
作为sdouglass建议,Spring MVC的自动检测杰克逊并建立MappingJacksonHttpMessageConverter从JSON处理转化成/。 但我确实需要显式配置的转换器来得到它的工作,因为他还指出。
我添加以下内容,我卷曲GET请求是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}]
但是,下列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给我的答案的问题。
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
我改变了我的卷曲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
希望有人认为这是有用的。
Answer 2:
如果我没有记错的春天文档说Spring MVC的将自动检测在classpath杰克逊,并成立了MappingJacksonHttpMessageConverter处理转换为从JSON /,但我想我已经经历过的情况下,我不得不手动/显式地配置转换器,以获得事情的工作。 你可能想尝试添加这对你的MVC XML配置:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
</list>
</property>
</bean>
更新 :正是这种加正确格式化JSON被张贴,看到https://stackoverflow.com/a/10363876/433789
Answer 3:
其2014年和我想一些更新添加到这个问题,它帮我解决了同样的问题。
代码更新,以取代过时的AnnotationMethodHandlerAdapter上春3.2
@组态 公共类的AppConfig { @Bean public RequestMappingHandlerAdapter annotationMethodHandlerAdapter() { final RequestMappingHandlerAdapter annotationMethodHandlerAdapter = new RequestMappingHandlerAdapter(); final MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJackson2HttpMessageConverter(); List<HttpMessageConverter<?>> httpMessageConverter = new ArrayList<HttpMessageConverter<?>>(); httpMessageConverter.add(mappingJacksonHttpMessageConverter); String[] supportedHttpMethods = { "POST", "GET", "HEAD" }; annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverter); annotationMethodHandlerAdapter.setSupportedMethods(supportedHttpMethods); return annotationMethodHandlerAdapter; } }
HTTP / 1.1 415不支持的媒体类型错误
花费许多时间试图为什么我仍然即使添加了正确的JSON配置我终于明白了,问题是不与服务器端但与客户端后,得到一个415错误弄清楚之后。 为了让Spring来接受你的JSON你必须确保你要发送两个“内容类型:应用程序/ JSON”和“接受:应用/ JSON”作为您的HTTP标头的一部分。 对我来说特别是一个Android应用程序HttpURLConnection的,我不得不将其设置为:
public static String doPost(final String urlString,final String requestBodyString) throws IOException {
final URL url = new URL(urlString);
final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setChunkedStreamingMode(0);
urlConnection.connect();
final PrintWriter out = new PrintWriter(urlConnection.getOutputStream());
out.print(requestBodyString);
out.close();
final InputStream in = new BufferedInputStream(urlConnection.getInputStream());
final String response = readIt(in);
in.close(); //important to close the stream
return response;
} finally {
urlConnection.disconnect();
}
}
Answer 4:
尝试添加的东西在你的POST请求的描述符。 也就是说,增加curl
头:
Content-Type: application/json
如果不加它, curl
将使用默认text/html
不管你实际发送。
此外,在PurchaseController.create()
必须添加所接受的类型是application/json
。
Answer 5:
我有同样的问题,这是由我的代码中两个变化解决:
- 缺少@PathVariable在我的方法的说法,我的方法没有任何
继我SpringConfig类的方法,因为一个我曾与处理器拦截器已被废弃,并给予一定的问题:
public RequestMappingHandlerAdapter RequestMappingHandlerAdapter() { final RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter(); final MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter(); final String[] supportedHttpMethods = { "POST", "GET", "HEAD" }; requestMappingHandlerAdapter.getMessageConverters().add(0, mappingJacksonHttpMessageConverter); requestMappingHandlerAdapter.setSupportedMethods(supportedHttpMethods); return requestMappingHandlerAdapter; }
Answer 6:
下面是类似约拉姆givon的回答一个单元测试的解决方案- https://stackoverflow.com/a/22516235/1019307 。
public class JSONFormatTest
{
MockMvc mockMvc;
// The controller used doesn't seem to be important though YMMV
@InjectMocks
ActivityController controller;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
this.mockMvc = standaloneSetup(controller).setMessageConverters(new MappingJackson2HttpMessageConverter())
.build();
}
@Test
public void thatSaveNewDataCollectionUsesHttpCreated() throws Exception
{
String jsonContent = getHereJSON02();
this.mockMvc
.perform(
post("/data_collections").content(jsonContent).contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isCreated());
}
private String getHereJSON01()
{
return "{\"dataCollectionId\":0,\"name\":\"Sat_016\",\"type\":\"httpUploadedFiles\"," ...
}
}
运行单元测试和print()
应打印出MockHttpServletRequest包括异常。
在Eclipse(不知道如何做到这一点在其他IDE),单击例外链接和属性对话框,该异常就应开放有关。 勾选“启用”框上破该异常。
调试单元测试和Eclipse将打破异常上。 检查应该发现问题。 在我的情况,那是因为我在JSON有两个相同的实体。
Answer 7:
我经历过一次,最后加入jar文件杰克逊映射器,asl.jar解决它。 去检查,如果你已经囊括了所有这些依赖虽然例外本身并没有告诉ü这一点。
而你真的不需要明确配置的bean,而你不需要把“消耗”在@RequestMapping声明。 我使用Spring 3.1 BTW。
的contentType:“应用/ JSON”是你需要配置唯一的一个。 是的,客户端。
Answer 8:
试着在你的应用程序配置中添加以下代码
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</mvc:message-converters>
Answer 9:
我有同样的问题,我解决它。
1添加MappingJackson2HttpMessageConverter如在该线程描述(也见第4 http://www.baeldung.com/spring-httpmessageconverter-rest )
2使用正确的命令(与逃逸符号):
curl -i -X POST -H "Content-Type:application/json" -d "{\"id\":\"id1\",\"password\":\"password1\"}" http://localhost:8080/user
文章来源: Posting JSON to REST API