2012-11-01 8 views
9

मेरे पास एक साधारण आरईएसटी एपीआई है, स्प्रिंग एमवीसी @Controller एस और @RequestMapping का उपयोग करके निर्माण करें। मैं मेटाडेटा के साथ अतिरिक्त प्रदान करने के लिए प्रतिक्रिया लपेटना शुरू करना चाहता हूं।स्प्रिंग एमवीसी: रैपिंग एपीआई प्रतिक्रियाओं के लिए उचित विस्तार बिंदु

उदाहरण के लिए

, एक फोन है कि वापसी होगी

HTTP GET: /users/1 
{ 
    "userName" : "Jack Jackerson" 
} 

मैं लपेट करना चाहते हैं को देखते हुए, इस प्रकार है:

{ 
    "metadata" : 
    { 
     "callLimit" : "50", 
     "callsRemaining" : "49" 
    }, 
    "result" : 
    { 
     "userName" : "Jack Jackerson" 
    } 
} ..etc.. 

साथ ही, मैं मानकों के मानक सेट का समर्थन करना चाहते हैं सूचियों के प्रबंधन के लिए (limit और offset)।

यह सब एपीआई तरीकों से छू के रूप में, मैं कुछ वसंत आंतरिक सेवा के एक डेकोरेटर के रूप में यह लागू करना चाहते हैं, तो तरीकों खुद को उनके वास्तविक तर्क पर ध्यान केंद्रित है, और इस बॉयलरप्लेट सामान केंद्रीकृत रख सकते हैं।

मैंने HttpMessageConverter को सजाने के मार्ग को शुरू कर दिया है, और उन्हें सजावटी के साथ लपेट लिया है।

हालांकि, यह मुझे उन तरीकों के लिए इनबाउंड अनुरोध तक पहुंच प्रदान नहीं करता है जो @RequestBody घोषित नहीं करते हैं। (कई नहीं)

आदर्श रूप से, मुझे स्टैक में उच्च होना चाहिए - RequestResponseBodyMethodProcessor.writeWithMessageConverters() एक अच्छे उम्मीदवार की तरह दिखता है, लेकिन मुझे नहीं पता कि यहां कैसे हुक करना है।

इस प्रकार के एपीआई-वाइड प्रसंस्करण अनुरोध/प्रतिक्रियाओं को लागू करने के लिए स्प्रिंग एमवीसी के साथ कौन से विकल्प उपलब्ध हैं?

उत्तर

6

यहाँ कार्यान्वयन मैं प्रयोग किया जाता है:

public class MetadataInjectingReturnValueHandler implements HandlerMethodReturnValueHandler { 

    private final HandlerMethodReturnValueHandler delegate; 

    public MetadataInjectingReturnValueHandler(HandlerMethodReturnValueHandler delegate) 
    { 
     this.delegate = delegate; 
    } 
    @Override 
    public boolean supportsReturnType(MethodParameter returnType) { 
     return delegate.supportsReturnType(returnType); 
    } 

    @Override 
    public void handleReturnValue(Object returnValue, 
      MethodParameter returnType, ModelAndViewContainer mavContainer, 
      NativeWebRequest webRequest) throws Exception { 
     returnValue = wrapResult(returnValue); //Omitted 
     delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest); 
    } 
} 



@Component 
public class MetadataInjectionFactoryBean implements InitializingBean { 

    @Autowired 
    private RequestMappingHandlerAdapter adapter; 
    @Override 
    public void afterPropertiesSet() throws Exception { 
     HandlerMethodReturnValueHandlerComposite returnValueHandlers = adapter.getReturnValueHandlers(); 
     List<HandlerMethodReturnValueHandler> handlers = Lists.newArrayList(returnValueHandlers.getHandlers()); 
     decorateHandlers(handlers); 
     adapter.setReturnValueHandlers(handlers); 
    } 
    private void decorateHandlers(List<HandlerMethodReturnValueHandler> handlers) { 
     for (HandlerMethodReturnValueHandler handler : handlers) { 
      if (handler instanceof RequestResponseBodyMethodProcessor) 
      { 
       MetadataInjectingReturnValueHandler decorator = new MetadataInjectingReturnValueHandler(handler); 
       int index = handlers.indexOf(handler); 
       handlers.set(index, decorator); 
       log.info("Metadata Injecting decorator wired up"); 
       break; 
      } 
     }  
    } 

} 
+0

पूरी तरह से काम किया। धन्यवाद! –

+0

मुझे लगता है कि ['@ ControllerAdvice'] का उपयोग करना संभव है (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-controller-advice) इस समाधान को सरल बनाने के लिए ['ResponseBodyAdvice'] के साथ संयुक्त (https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyAdvice.html) । –

+0

@AmirAbiri, यह आपको प्रतिक्रिया के प्रकार को बदलने की अनुमति नहीं देता है। आप केवल कुछ डेटा के साथ प्रतिक्रिया को समृद्ध कर सकते हैं, लेकिन ऑब्जेक्ट को अन्य संरचना के साथ लपेटने के लिए नहीं। –