1 package cn.home1.oss.lib.webmvc.internal;
2
3 import static org.springframework.web.HttpMessageConverterUtils.defaultContentNegotiationManager;
4 import static org.springframework.web.HttpMessageConverterUtils.defaultHttpMessageConverters;
5
6 import lombok.Getter;
7 import lombok.NonNull;
8 import lombok.Setter;
9 import lombok.extern.slf4j.Slf4j;
10
11 import org.springframework.beans.factory.InitializingBean;
12 import org.springframework.core.MethodParameter;
13 import org.springframework.core.env.PropertyResolver;
14 import org.springframework.http.MediaType;
15 import org.springframework.http.converter.HttpMessageConverter;
16 import org.springframework.web.HttpMediaTypeNotAcceptableException;
17 import org.springframework.web.HttpMessageConverterUtils;
18 import org.springframework.web.accept.ContentNegotiationManager;
19 import org.springframework.web.accept.FixedContentNegotiationStrategy;
20 import org.springframework.web.context.request.NativeWebRequest;
21 import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
22 import org.springframework.web.method.support.ModelAndViewContainer;
23 import org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor;
24
25 import java.util.List;
26
27
28
29
30 @Slf4j
31 public class DefaultHttpEntityMethodProcessor implements HandlerMethodReturnValueHandler, InitializingBean {
32
33
34
35
36
37
38
39
40
41
42 @Getter
43 private ContentNegotiationManager contentNegotiationManager;
44
45
46
47
48 @Getter
49 @Setter
50 private MediaType defaultContentType;
51
52
53
54
55
56
57 @NonNull
58 private List<HttpMessageConverter<?>> messageConverters;
59
60
61 private HandlerMethodReturnValueHandler responseProcessor;
62
63 private HandlerMethodReturnValueHandler fallbackResponseProcessor;
64
65 @Override
66 public boolean supportsReturnType(final MethodParameter returnType) {
67 return this.responseProcessor.supportsReturnType(returnType) ||
68 this.fallbackResponseProcessor.supportsReturnType(returnType);
69 }
70
71
72
73
74
75
76
77
78
79
80 @Override
81 public void handleReturnValue(
82 final Object returnValue, final MethodParameter returnType,
83 final ModelAndViewContainer mavContainer, final NativeWebRequest webRequest
84 ) throws Exception {
85 try {
86 this.responseProcessor.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
87 } catch (final HttpMediaTypeNotAcceptableException ex) {
88 if (log.isDebugEnabled()) {
89 log.debug("Requested media type is not supported, falling back to default one", ex);
90 }
91 this.fallbackResponseProcessor.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
92 }
93 }
94
95 @Override
96 public void afterPropertiesSet() throws Exception {
97 this.responseProcessor = new HttpEntityMethodProcessor(
98 this.messageConverters,
99 this.contentNegotiationManager
100 );
101 this.fallbackResponseProcessor = new HttpEntityMethodProcessor(
102 this.messageConverters,
103 new ContentNegotiationManager(
104 new FixedContentNegotiationStrategy(this.defaultContentType)
105 )
106 );
107 }
108
109 public void setContentNegotiationManager(final ContentNegotiationManager contentNegotiationManager) {
110 this.contentNegotiationManager = contentNegotiationManager;
111 }
112
113 public List<HttpMessageConverter<?>> getMessageConverters() {
114 return this.messageConverters;
115 }
116
117 public void setMessageConverters(final List<HttpMessageConverter<?>> messageConverters) {
118 this.messageConverters = messageConverters;
119 }
120
121 public static DefaultHttpEntityMethodProcessor defaultHttpEntityMethodProcessor(
122 final PropertyResolver propertyResolver,
123 final Object objectMapper
124 ) {
125
126
127
128 final ContentNegotiationManager defaultContentNegotiationManager = defaultContentNegotiationManager();
129 final List<HttpMessageConverter<?>> defaultHttpMessageConverters = defaultHttpMessageConverters(
130 propertyResolver, objectMapper);
131
132 final DefaultHttpEntityMethodProcessor processor = new DefaultHttpEntityMethodProcessor();
133 processor.setContentNegotiationManager(defaultContentNegotiationManager);
134 processor.setMessageConverters(defaultHttpMessageConverters);
135 return processor;
136 }
137 }