Spring: Response Entity를 사용하여 빈 HTTP 응답을 반환하는 것이 작동하지 않습니다.
우리는 REST API를 Spring(4.1.1.)과 함께 구현하고 있습니다.특정 HTTP 요청의 경우 응답으로 본문이 없는 헤드를 반품하고 싶습니다.하지만 사용하는것은ResponseEntity<Void>
효과가 없는 것 같습니다.A와 함께 호출될 때MockMvc
테스트하면 406(허용되지 않음)이 반환됩니다.사용.ResponseEntity<String>
매개 변수 값 없이(new ResponseEntity<String>( HttpStatus.NOT_FOUND )
) 잘 작동합니다.
방법:
@RequestMapping( method = RequestMethod.HEAD, value = Constants.KEY )
public ResponseEntity<Void> taxonomyPackageExists( @PathVariable final String key ) {
LOG.debug( "taxonomyPackageExists queried with key: {0}", key ); //$NON-NLS-1$
final TaxonomyKey taxonomyKey = TaxonomyKey.fromString( key );
LOG.debug( "Taxonomy key created: {0}", taxonomyKey ); //$NON-NLS-1$
if ( this.xbrlInstanceValidator.taxonomyPackageExists( taxonomyKey ) ) {
LOG.debug( "Taxonomy package with key: {0} exists.", taxonomyKey ); //$NON-NLS-1$
return new ResponseEntity<Void>( HttpStatus.OK );
} else {
LOG.debug( "Taxonomy package with key: {0} does NOT exist.", taxonomyKey ); //$NON-NLS-1$
return new ResponseEntity<Void>( HttpStatus.NOT_FOUND );
}
}
테스트 케이스(TestNG):
public class TaxonomyQueryControllerTest {
private XbrlInstanceValidator xbrlInstanceValidatorMock;
private TaxonomyQueryController underTest;
private MockMvc mockMvc;
@BeforeMethod
public void setUp() {
this.xbrlInstanceValidatorMock = createMock( XbrlInstanceValidator.class );
this.underTest = new TaxonomyQueryController( this.xbrlInstanceValidatorMock );
this.mockMvc = MockMvcBuilders.standaloneSetup( this.underTest ).build();
}
@Test
public void taxonomyPackageDoesNotExist() throws Exception {
// record
expect( this.xbrlInstanceValidatorMock.taxonomyPackageExists( anyObject( TaxonomyKey.class ) ) ).andStubReturn(
false );
// replay
replay( this.xbrlInstanceValidatorMock );
// do the test
final String taxonomyKey = RestDataFixture.taxonomyKeyString;
this.mockMvc.perform( head( "/taxonomypackages/{key}", taxonomyKey ).accept( //$NON-NLS-1$
MediaType.APPLICATION_XML ) ).andExpect( status().isNotFound() );
}
}
이 스택 추적 실패:
FAILED: taxonomyPackageDoesNotExist
java.lang.AssertionError: Status expected:<404> but was:<406>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:652)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:153)
at de.zeb.control.application.xbrlstandalonevalidator.restservice.TaxonomyQueryControllerTest.taxonomyPackageDoesNotExist(TaxonomyQueryControllerTest.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
참고: 이는 질문에 언급된 버전인 4.1.1에 해당합니다.풀어주다.
스프링 MVC 핸들 AResponseEntity
수익률을 통한 수익HttpEntityMethodProcessor
.
언제.ResponseEntity
값에 본문이 설정되어 있지 않습니다. 당신의 토막글의 경우처럼 말이죠.HttpEntityMethodProcessor
의 매개 변수화로부터 응답 본문에 대한 내용 유형을 결정하려고 합니다.ResponseEntity
의 서명에 있는 반환 형식@RequestMapping
핸들러 방식
그래서.
public ResponseEntity<Void> taxonomyPackageExists( @PathVariable final String key ) {
그 타입은Void
.HttpEntityMethodProcessor
그러면 등록된 모든 것을 순환할 것입니다.HttpMessageConverter
예를 들어, 하나의 본문을 작성할 수 있는 것을 찾습니다.Void
type. 구성에 따라 찾을 수도 없고 찾을 수도 없습니다.
발견된 내용이 있으면 해당 본문이 요청 문서에 제공된 유형과 일치하는 내용 유형으로 작성되었는지 확인해야 합니다.Accept
머리글,application/xml
자네 같은 경우에는
이 모든 점검 후에, 그런 것은 없습니다.HttpMessageConverter
존재합니다. Spring MVC는 허용 가능한 응답을 생성할 수 없다고 결정하고 따라서 406 Not Acceptable HTTP 응답을 반환합니다.
와 함께ResponseEntity<String>
, 봄은 사용할 것입니다.String
대응 기관으로서 그리고 발견으로서.StringHttpMessageConverter
조련사로서그 이후로StringHttpMessageHandler
모든 미디어 유형에 대한 콘텐츠를 생성할 수 있습니다(에 제공됨).Accept
헤더), 그것은 다음을 처리할 수 있을 것입니다.application/xml
당신의 고객이 요청하는 것입니다.
스프링 MVC는 그 후 차체가 아래에 있는 경우 406만 리턴하도록 변경되었습니다.ResponseEntity
그렇지 않음null
. 보다 최신 버전의 Spring MVC를 사용하는 경우에는 원래 질문에서 동작을 볼 수 없습니다.
iddy85의 해결책에서, 제안하는 것처럼 보이는ResponseEntity<?>
, 신체에 대한 유형은 다음과 같이 추론될 것입니다.Object
. 클래스 경로에 올바른 라이브러리가 있는 경우.Jackson (버전 > 2.5.0)과 그 XML 확장자인 Spring MVC는 다음에 접근할 수 있을 것입니다.MappingJackson2XmlHttpMessageConverter
생산에 사용할 수 있는application/xml
활자로는Object
. 그들의 해결책은 이런 조건에서만 작동합니다.그렇지 않으면 위에서 설명한 것과 같은 이유로 실패합니다.
Spring 4 MVC Response Entity.BodyBuilder 및 Response Entity Enhancements 예는 다음과 같이 쓸 수 있습니다.
....
return ResponseEntity.ok().build();
....
return ResponseEntity.noContent().build();
업데이트:
반환된 값이 다음과 같은 경우Optional
, 만, 되었습니다 이 있습니다.ok()
아니면notFound()
:
return ResponseEntity.of(optional)
2: 할 수 .OK(200)
public void taxonomyPackageExists(...
에 대한 NO_CONTENT(204)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void taxonomyPackageExists(...
또한 문서를 볼 때 약간 깨끗해 보이는 유형 매개변수와 Spring이 의도한 바를 지정할 수 없습니다.
@RequestMapping(method = RequestMethod.HEAD, value = Constants.KEY )
public ResponseEntity taxonomyPackageExists( @PathVariable final String key ){
// ...
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
를 조금 해서 를 . 다음을 시도해보고 코드를 조금 수정해서 사용해보세요.HttpStatus.NO_CONTENT
즉 204 대신 HttpStatus.OK
서버가 요청을 이행했지만 개체를 반환할 필요가 없으므로 업데이트된 메타정보를 반환할 수 있습니다.응답에는 개체 헤더의 형태로 새로운 또는 업데이트된 메타 정보가 포함될 수 있으며, 존재하는 경우 요청된 변형과 연관되어야 합니다.
204의 경우 T 값은 무시되지만 404의 경우에는 무시되지 않습니다.
public ResponseEntity<?> taxonomyPackageExists( @PathVariable final String key ) {
LOG.debug( "taxonomyPackageExists queried with key: {0}", key ); //$NON-NLS-1$
final TaxonomyKey taxonomyKey = TaxonomyKey.fromString( key );
LOG.debug( "Taxonomy key created: {0}", taxonomyKey ); //$NON-NLS-1$
if ( this.xbrlInstanceValidator.taxonomyPackageExists( taxonomyKey ) ) {
LOG.debug( "Taxonomy package with key: {0} exists.", taxonomyKey ); //$NON-NLS-1$
return new ResponseEntity<T>(HttpStatus.NO_CONTENT);
} else {
LOG.debug( "Taxonomy package with key: {0} does NOT exist.", taxonomyKey ); //$NON-NLS-1$
return new ResponseEntity<T>( HttpStatus.NOT_FOUND );
}
}
Spring 5.2 이상의 경우에는 다음과 같습니다.
@PostMapping("/foo")
ResponseEntity<Void> foo(@PathVariable UUID fooId) {
return fooService.findExam(fooId)
.map(uri -> ResponseEntity.noContent().<Void>build())
.orElse(ResponseEntity.notFound().build());
}
개인적으로 빈 응답을 처리하기 위해 통합 테스트에서 MockMvcResponse 개체를 다음과 같이 사용합니다.
MockMvcResponse response = RestAssuredMockMvc.given()
.webAppContextSetup(webApplicationContext)
.when()
.get("/v1/ticket");
assertThat(response.mockHttpServletResponse().getStatus()).isEqualTo(HttpStatus.NO_CONTENT.value());
컨트롤러에서 빈 응답을 다음과 같은 특정한 경우에 반환합니다.
return ResponseEntity.noContent().build();
언급URL : https://stackoverflow.com/questions/26550124/spring-returning-empty-http-responses-with-responseentityvoid-doesnt-work
'programing' 카테고리의 다른 글
jQuery - 선택한 옵션 사용 안 함 (0) | 2023.10.06 |
---|---|
c에 데이터 유형이 없는 변수 선언 (0) | 2023.10.06 |
초기화되지 않은 컬렉션 PL/SQL 참조 (0) | 2023.10.06 |
UITextField 반환 키에 대한 작업을 추가하는 방법은 무엇입니까? (0) | 2023.10.06 |
strpbrk는 무엇의 약자입니까? (0) | 2023.10.06 |