>
GET 를 제공하는 컨트롤러가 있다고 가정하십시오.  요청하고 Bean을 JSON으로 직렬화하고 리턴하여 IllegalArgumentException 에 대한 예외 핸들러를 제공합니다.  그것은 서비스에서 제기 될 수 있습니다 :

@RequestMapping(value = "/meta/{itemId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public MetaInformation getMetaInformation(@PathVariable int itemId) {
    return myService.getMetaInformation(itemId);
}
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ResponseBody
public String handleIllegalArgumentException(IllegalArgumentException ex) {
    return ExceptionUtils.getStackTrace(ex);
}

메시지 변환기 :

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

이제 브라우저에서 지정된 URL을 요청하면 올바른 JSON 응답이 표시됩니다. 그러나 예외가 발생하면 문자열로 된 예외도 JSON으로 변환되지만 StringHttpMessageConverter 에서 처리되도록하고 싶습니다.  (결과 text/plain  MIME 유형). 어떻게해야합니까?

사진을 더 완전하고 복잡하게 만들기 위해 다음 핸들러도 있다고 가정합니다.

@RequestMapping(value = "/version", method = RequestMethod.GET)
@ResponseBody
public String getApplicationVersion() {
    return "1.0.12";
}

이 핸들러는 리턴 문자열이 두 MappingJackson2HttpMessageConverter 에 의해 직렬화 될 수 있도록합니다.  그리고 StringHttpMessageConverter  통과 한 Accept-type 에 따라  클라이언트에 의해. 반환 유형과 값은 다음과 같아야합니다.

+ ---- + --------------------- + ---------------------- -+ ------------------ + ----------------------------- -------- +
| NN | URL | 수락 유형 | 컨텐츠 유형 | 메시지 변환기 |
| | | 요청 헤더 | 응답 헤더 | |
+ ---- + --------------------- + ---------------------- -+ ------------------ + ----------------------------- -------- +
| 1. |/버전 | 텍스트/html;*/* | 텍스트/일반 | StringHttpMessageConverter |
| 2. |/버전 | 응용 프로그램/json;*/* | 응용 프로그램/json | MappingJackson2HttpMessageConverter |
| 3. |/meta/1 | 텍스트/html;*/* | 응용 프로그램/json | MappingJackson2HttpMessageConverter |
| 4. |/meta/1 | 응용 프로그램/json;*/* | 응용 프로그램/json | MappingJackson2HttpMessageConverter |
| 5. |/meta/0 (예외) | 텍스트/html;*/* | 텍스트/일반 | StringHttpMessageConverter |
| 6. |/meta/0 (예외) | 응용 프로그램/json;*/* | 텍스트/일반 | StringHttpMessageConverter |
+ ---- + --------------------- + ---------------------- -+ ------------------ + ----------------------------- -------- +

  • 답변 # 1

    나는 produces = MediaType.APPLICATION_JSON_VALUE 를 제거 생각   @RequestMapping 에서  Wyzwyz의  원하는 결과를 제공합니다.

    응답 유형은 수락 헤더의 내용 유형 값에 따라 협상됩니다.

    <시간>

    수정

    이 시나리오 3,4를 다루지 않기 때문에 여기 getMetaInformation 와 함께 작동하는 솔루션이 있습니다.  직접 :

    ResponseEntity.class
    
    

  • 답변 # 2

    문제와 관련된 몇 가지 측면이 있습니다 :

    @ExceptionHandler(Exception.class) public ResponseEntity<String> handleIllegalArgumentException(Exception ex) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.TEXT_PLAIN); return new ResponseEntity<String>(ex.getMessage(), headers, HttpStatus.BAD_REQUEST); }  catch-all MIME 유형 StringHttpMessageConverter 추가   */* 동안 지원되는 미디어 유형 목록   MappingJackson2HttpMessageConverter 에 묶여있다  만.

    와이즈 비즈   application/json 를 제공하고 있습니다 이 값은 @RequestMapping 에 저장됩니다.  ( produces = ... 참조) ) 및 오류 처리기가 호출되면이 MIME 유형이 자동으로 상속되어 사용됩니다.

    간단한 경우 해결책은 HttpServletRequest 를 넣는 것입니다.  목록에서 첫 번째 :

    RequestMappingInfoHandlerMapping.handleMatch()
    
    

    또한 StringHttpMessageConverter 를 제거   <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <array> <util:constant static-field="org.springframework.http.MediaType.TEXT_PLAIN" /> </array> </property> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> 에서  주석 :

    produces
    
    

    지금 :

    @RequestMapping   @RequestMapping(value = "/meta/{itemId}", method = RequestMethod.GET) @ResponseBody public MetaInformation getMetaInformation(@PathVariable int itemId) { return myService.getMetaInformation(itemId); } 만 모든 유형을 버립니다.  처리 할 수 ​​있음 ( StringHttpMessageConverter MappingJackson2HttpMessageConverter 등) 더 전달 될 수 있도록 허용

    (5, 6) 시나리오에서 예외가 발생한 경우 MetaInformation  우선권을 갖습니다.

    지금까지는 좋지만 불행히도 java.util.Collection 를 사용하면 상황이 더 복잡해집니다. . 핸들러 리턴 유형 StringHttpMessageConverter  이 메시지 변환기는이 유형을 ObjectToStringHttpMessageConverter 로 변환 할 수 있다고보고합니다. . 컬렉션 요소 유형이 지워지고 java.util.Collection<MetaInformation> 라는 사실에서 한계가 발생합니다.  방법은 java.lang.String 를 얻는다  그러나 변환 단계 AbstractHttpMessageConverter.canWrite(Class<?> clazz, MediaType mediaType) 에 관해서는 확인을위한 클래스  실패합니다. 문제를 해결하기 위해 우리는 java.util.Collection<?> 를 유지   ObjectToStringHttpMessageConverter 를 위해  JSON 변환기를 사용해야하는 주석이지만 예외 핸들러에 대한 올바른 내용 유형을 강제하기 위해 produces 를 지 웁니다.   @RequestMapping 의 속성 :

    HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE
    
    

    컨텍스트는 원래와 동일하게 유지됩니다 :

    HttpServletRequest
    
    

    현재 시나리오 (1,2,3,4)는 컨텐츠 유형 협상으로 인해 올바르게 처리되며 시나리오 (5,6)는 예외 처리기에서 처리됩니다.

    대신 콜렉션 반환 유형을 배열로 대체 할 수 있으며 솔루션 # 1을 다시 적용 할 수 있습니다 :

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public String handleIllegalArgumentException(HttpServletRequest request, IllegalArgumentException ex) {
        request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
        return ExceptionUtils.getStackTrace(ex);
    }
    @RequestMapping(value = "/meta", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Collection<MetaInformation> getMetaInformations() {
        return myService.getMetaInformations();
    }
    
    
    <시간>

    토론 :

    나는 그 <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> <bean class="org.springframework.http.converter.ObjectToStringHttpMessageConverter"> <property name="conversionService"> <bean class="org.springframework.context.support.ConversionServiceFactoryBean" /> </property> <property name="supportedMediaTypes"> <array> <util:constant static-field="org.springframework.http.MediaType.TEXT_PLAIN" /> </array> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> 생각  값에서 클래스를 상속해서는 안되고 메소드 서명에서 클래스를 상속해야합니다.

    @RequestMapping(value = "/meta", method = RequestMethod.GET) @ResponseBody public MetaInformation[] getMetaInformations() { return myService.getMetaInformations().toArray(); }

    AbstractMessageConverterMethodProcessor.writeWithMessageConverters()  다음으로 변경해야합니다 :

    Type returnValueType = returnType.getGenericParameterType();

    또는 (클래스 기반 컨버터가 너무 제한적인 경우)

    HttpMessageConverter.canWrite(Class<?> clazz, MediaType mediaType)

    그러면 매개 변수화 된 유형을 올바르게 처리하고 솔루션 # 1을 다시 적용 할 수 있습니다.

    canWrite(Type returnType, MediaType mediaType)

  • 이전 로드 테스트를 위해 빠른 소켓 작성 및 소멸을 시도 할 때"javanetbindexception - 이미 사용중인 주소"
  • 다음 javascript - fabricjs - 그룹 크기를 조정할 때 객체 위치를 고정 상태로 유지