이것은 이상적인 솔루션이 아닙니다. 내 두 번째 대답을 참조하십시오.
나는 이것을 ModelAndViewResolver
을 사용하여 해결했다. 직접적으로 기본 처리가 발생하기 전에 그들이 항상 시작될 것임을 알면서 특권을 가지고 AnnotationMethodHandlerAdapter
으로 직접 등록 할 수 있습니다. 따라서, 봄의 설명서 -
/**
* Set a custom ModelAndViewResolvers to use for special method return types.
* <p>Such a custom ModelAndViewResolver will kick in first, having a chance to resolve
* a return value before the standard ModelAndView handling kicks in.
*/
public void setCustomModelAndViewResolver(ModelAndViewResolver customModelAndViewResolver) {
this.customModelAndViewResolvers = new ModelAndViewResolver[] {customModelAndViewResolver};
}
ModelAndViewResolver
인터페이스를 살펴보면, 나는 그것이 핸들러 메소드가 어떻게 작동하는지에 일부 기능을 확장하는 데 필요한 모든 인수를 포함 것을 알고 있었다. resolveModelAndView
의 모든 맛있는 인수에
public interface ModelAndViewResolver {
ModelAndView UNRESOLVED = new ModelAndView();
ModelAndView resolveModelAndView(Method handlerMethod,
Class handlerType,
Object returnValue,
ExtendedModelMap implicitModel,
NativeWebRequest webRequest);
}
봐! 나는 Spring이 요청에 대해 알고있는 거의 모든 것에 접근 할 수있다. 여기에 내가 (외부) 단방향 방식으로 제외 MappingJacksonHttpMessageConverter
과 매우 유사한 역할을하도록 인터페이스를 구현하는 방법은 다음과 같습니다
public class JsonModelAndViewResolver implements ModelAndViewResolver {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
public static final MediaType DEFAULT_MEDIA_TYPE = new MediaType("application", "json", DEFAULT_CHARSET);
private boolean prefixJson = false;
public void setPrefixJson(boolean prefixJson) {
this.prefixJson = prefixJson;
}
/**
* Converts Json.mixins() to a Map<Class, Class>
*
* @param jsonFilter Json annotation
* @return Map of Target -> Mixin classes
*/
protected Map<Class<?>, Class<?>> getMixins(Json jsonFilter) {
Map<Class<?>, Class<?>> mixins = new HashMap<Class<?>, Class<?>>();
if(jsonFilter != null) {
for(JsonMixin jsonMixin : jsonFilter.mixins()) {
mixins.put(jsonMixin.target(), jsonMixin.mixin());
}
}
return mixins;
}
@Override
public ModelAndView resolveModelAndView(Method handlerMethod, Class handlerType, Object returnValue, ExtendedModelMap implicitModel, NativeWebRequest webRequest) {
if(handlerMethod.getAnnotation(Json.class) != null) {
try {
HttpServletResponse httpResponse = webRequest.getNativeResponse(HttpServletResponse.class);
httpResponse.setContentType(DEFAULT_MEDIA_TYPE.toString());
OutputStream out = httpResponse.getOutputStream();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setMixInAnnotations(getMixins(handlerMethod.getAnnotation(Json.class)));
JsonGenerator jsonGenerator =
objectMapper.getJsonFactory().createJsonGenerator(out, JsonEncoding.UTF8);
if (this.prefixJson) {
jsonGenerator.writeRaw("{} && ");
}
objectMapper.writeValue(jsonGenerator, returnValue);
out.flush();
out.close();
return null;
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return UNRESOLVED;
}
}
위에서 사용하는 유일한 사용자 정의 클래스가 mixins
라는 하나 개의 매개 변수를 포함하는 내 주석 클래스 @Json
입니다. 다음은 컨트롤러 측에서 구현하는 방법입니다.
@Controller
public class Controller {
@Json({ @JsonMixin(target=MyTargetObject.class, mixin=MyTargetMixin.class) })
@RequestMapping(value="/my-rest/{id}/my-obj", method=RequestMethod.GET)
public @ResponseBody List<MyTargetObject> getListOfFoo(@PathVariable("id") Integer id) {
return MyServiceImpl.getInstance().getBarObj(id).getFoos();
}
}
꽤 멋진 단순함입니다. ModelAndViewResolver는 반환 객체를 JSON으로 자동 변환하고 주석이 달린 믹스 인을 적용합니다.
하나의 "아래쪽"(이것을 부르면)은 스프링 2로 되돌아 가야합니다.새로운 3.0 태그가 ModelAndViewResolver를 직접 설정하는 것을 허용하지 않기 때문에 이것을 구성하는 5 가지 방법. 어쩌면 그들은 단지 이것을 간과 했는가?
하여 이전 구성 (사용 스프링 3.1 스타일)
<mvc:annotation-driven />
나의 새로운 구성 (사용 스프링 2.5 스타일)
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="customModelAndViewResolvers">
<list>
<bean class="my.package.mvc.JsonModelAndViewResolver" />
</list>
</property>
</bean>
^^ 3.0 이상은 방법이 없습니다 커스텀 ModelAndViewResolver를 와이어 인합니다. 따라서 이전 스타일로 다시 전환하십시오.
가 여기에 사용자 지정 주석의 아래에 답을 게시 한 후
JSON
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Json {
/**
* A list of Jackson Mixins.
* <p>
* {@link http://wiki.fasterxml.com/JacksonMixInAnnotations}
*/
JsonMixin[] mixins() default {};
}
JsonMixin
public @interface JsonMixin {
public Class<? extends Serializable> target();
public Class<?> mixin();
}