我正在运行Spring Boot应用程序。请求/响应发送protobuf(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
,它甚至会抛出异常)。 {i}根本不处理HTTP输入消息。有没有办法解决这个问题?
答案 0 :(得分: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消息对象的默认实例。