[SPRING] JSON을 REST API에 게시
SPRINGJSON을 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 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);
}
}
AppConfig.java에 Jackson 구성을 추가했습니다.
@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;
}
}
내가 잘못 가고있는 어떤 생각?
감사
해결법
-
==============================
1.sdouglass가 제안한 것처럼 Spring MVC는 자동으로 Jackson을 감지하고 JSON과의 변환을 처리하는 MappingJacksonHttpMessageConverter를 설정합니다. 하지만 나는 명시 적으로 작동하도록 변환기를 구성하는 명확성이 필요했습니다.
sdouglass가 제안한 것처럼 Spring MVC는 자동으로 Jackson을 감지하고 JSON과의 변환을 처리하는 MappingJacksonHttpMessageConverter를 설정합니다. 하지만 나는 명시 적으로 작동하도록 변환기를 구성하는 명확성이 필요했습니다.
다음을 추가하고 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>
TRACE 레벨 디버깅을 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
내 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
잘만되면 누군가는 이것을 유용하다고 생각합니다.
-
==============================
2.스프링 문서가 스프링 캠퍼스를 자동으로 감지하고 JSON과의 변환을 처리하기 위해 MappingJacksonHttpMessageConverter를 설정한다고 말한 바 있습니다. 그러나 수동으로 / 명시 적으로 해당 변환기를 설정해야하는 상황을 경험 한 것 같습니다. 일할 것들. MVC config XML에이 값을 추가하려고 할 수 있습니다.
스프링 문서가 스프링 캠퍼스를 자동으로 감지하고 JSON과의 변환을 처리하기 위해 MappingJacksonHttpMessageConverter를 설정한다고 말한 바 있습니다. 그러나 수동으로 / 명시 적으로 해당 변환기를 설정해야하는 상황을 경험 한 것 같습니다. 일할 것들. MVC config 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를 참조하십시오.
-
==============================
3.2014 년에이 질문에 대한 몇 가지 업데이트를 추가하여 동일한 문제를 해결하는 데 도움이되었습니다.
2014 년에이 질문에 대한 몇 가지 업데이트를 추가하여 동일한 문제를 해결하는 데 도움이되었습니다.
왜 내가 올바른 JSON 구성을 추가 한 후에도 415 오류가 발생하는 이유를 알아 내려고 많은 시간을 보냈다. 마침내 문제는 서버 쪽이 아니라 클라이언트 쪽이었습니다. Spring이 JSON을 받아들이게하려면 http 헤더의 일부로 "Content-Type : application / json"과 "Accept : application / json"을 모두 전송해야합니다. 나를 위해 구체적으로 안드로이드 응용 프로그램 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(); } }
-
==============================
4.POST 요청에있는 설명자를 추가하십시오. 즉, 헤더를 말리기 위해 추가하십시오.
POST 요청에있는 설명자를 추가하십시오. 즉, 헤더를 말리기 위해 추가하십시오.
Content-Type: application/json
추가하지 않으면 curl은 실제로 보낸 내용에 관계없이 기본 text / html을 사용합니다.
또한, PurchaseController.create ()에서 당신은 받아 들여지는 타입이 application / json이라는 것을 추가해야만합니다.
-
==============================
5.내 코드에서 두 가지 변경 사항으로 해결 된 동일한 문제가 발생했습니다.
내 코드에서 두 가지 변경 사항으로 해결 된 동일한 문제가 발생했습니다.
-
==============================
6.다음은 yoram givon의 답변 - https://stackoverflow.com/a/22516235/1019307과 유사한 단위 테스트 솔루션입니다.
다음은 yoram 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에 동일한 엔티티가 2 개 있었기 때문입니다.
-
==============================
7.나는 jar 파일 jackson-mapper-asl.jar을 추가하여 한 번 경험했고 마침내 해결했습니다. 예외 자체가 그것을 알려주지는 않지만 모든 종속성을 포함했는지 확인하십시오.
나는 jar 파일 jackson-mapper-asl.jar을 추가하여 한 번 경험했고 마침내 해결했습니다. 예외 자체가 그것을 알려주지는 않지만 모든 종속성을 포함했는지 확인하십시오.
그리고 당신은 실제로 bean을 명시 적으로 설정할 필요가 없으며 @RequestMapping 문에 "consumes"를 넣을 필요가 없습니다. 저는 봄 3.1 btw를 사용하고 있습니다.
contentType : "application / json"만 구성해야합니다. 네, 고객 측.
-
==============================
8.앱 구성에 다음 코드를 추가하십시오.
앱 구성에 다음 코드를 추가하십시오.
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" ref="jacksonObjectMapper" /> </bean> </mvc:message-converters>
-
==============================
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
from https://stackoverflow.com/questions/10323957/posting-json-to-rest-api by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 주석에서 트랜잭션 주석이 작동하지 않음 (0) | 2019.01.11 |
---|---|
[SPRING] 스프링 웹 소켓에서 주제를 구독하는 모든 사용자를 찾는 방법 (0) | 2019.01.11 |
[SPRING] JdbcDaoSupport는 무엇을 위해 사용됩니까? (0) | 2019.01.11 |
[SPRING] Weblogic에 스프링 부트 응용 프로그램 배포 (0) | 2019.01.11 |
[SPRING] 왜 트랜잭션은 RuntimeException에서 롤백하지만 SQLException은 그렇지 않다. (0) | 2019.01.11 |