发布JSON以REST API(Posting JSON to REST API)

2019-06-23 23:49发布

我创建一个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年和我想一些更新添加到这个问题,它帮我解决了同样的问题。

  1. 代码更新,以取代过时的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; } } 
  2. 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:

我有同样的问题,这是由我的代码中两个变化解决:

  1. 缺少@PathVariable在我的方法的说法,我的方法没有任何
  2. 继我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