处理空请求体(protobuf3编码)

时间:2017-03-03 07:08:00

标签: spring spring-boot protocol-buffers

我正在运行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输入消息。有没有办法解决这个问题?

1 个答案:

答案 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消息对象的默认实例。