2017-03-03 144 views
1

我有一個Spring Boot應用程序正在運行。請求/響應發送protobuf(Protobuf3)編碼。處理空請求體(protobuf3編碼)

我(簡體)REST控制器:

@RestController 
public class ServiceController { 
    @RequestMapping(value = "/foo/{userId}", method = RequestMethod.POST) 
    public void doStuff(@PathVariable int userId, @RequestBody(required = false) Stuff.Request pbRequest) { 
     // Do stuff 
    } 
} 

我(簡體)protobuf3模式:

syntax = "proto3"; 

message Request { 
    int32 data = 1; 
} 

我的配置有可用的內容協商:

@Configuration 
public class ProtobufConfig { 
    @Bean 
    ProtobufHttpMessageConverter protobufHttpMessageConverter() { 
     return new ProtobufHttpMessageConverter(); 
    } 
} 

一切工作只要請求主體設置了一些字節,就像魅力一樣。但是如果只發送默認值,protobuf不會寫入任何字節。只要我有一個請求消息,其中包含data = 0生成的字節只是空的。在應用程序方面,請求主體是null,並且不會轉換爲protobuf消息(如果請求正文設置爲required = true,它甚至會引發異常)。 HTTP輸入消息根本沒有被ProtobufHttpMessageConverter處理。有辦法處理嗎?

回答

1

我找到了一種處理它的方法。但是,使用反射這是真的東西,我不希望有:

@ControllerAdvice 
public class RequestBodyAdviceChain implements RequestBodyAdvice { 

    @Override 
    public boolean supports(MethodParameter methodParameter, Type type, 
      Class< ? extends HttpMessageConverter<?>> aClass) { 
     return true; 
    } 

    @Override 
    public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, 
      Type type, Class< ? extends HttpMessageConverter<?>> aClass) { 
     try { 
      Class<?> cls = Class.forName(type.getTypeName()); 
      Method m = cls.getMethod("getDefaultInstance"); 
      return m.invoke(null); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return body; 
    } 

    @Override 
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, 
      Type type, Class< ? extends HttpMessageConverter<?>> aClass) throws IOException { 
     return httpInputMessage; 
    } 

    @Override 
    public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, 
      Class< ? extends HttpMessageConverter<?>> aClass) { 
     return body; 
    } 
} 

因此在一個空體的情況下,我創建的protobuf消息對象的默認實例。