web服务处理protobuf
webservice handling protobuf
我正在尝试使 Web 服务与 protobuf 和 json 一起工作。
问题在于我希望能够读取 inputStream 以构建我的原型(至少我没有看到另一种方式)。
我为 protobuf 创建了一个转换器:
public class ProtobufMessageConverter extends AbstractHttpMessageConverter<MyProto>{
@Override
protected boolean supports(Class<?> aClass) {
return MyProto.class.equals(aClass);
}
@Override
protected MyProto readInternal(Class<? extends MyProto> aClass, HttpInputMessage httpInputMessage)
throws IOException, HttpMessageNotReadableException {
return MyProto.parseFrom(httpInputMessage.getBody());
}
@Override
protected void writeInternal(MyProto proto, HttpOutputMessage httpOutputMessage)
throws IOException, HttpMessageNotWritableException {
OutputStream wr = httpOutputMessage.getBody();
wr.write(proto.toByteArray());
wr.close();
}
}
在我的 spring 配置中使用:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.test")
public class SpringMvcConfiguration extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {
httpMessageConverters.add(new ProtobufMessageConverter(new MediaType("application","octet-stream")));
addDefaultHttpMessageConverters(httpMessageConverters);
}
}
我的控制器:
@RequestMapping(value = "/proto", method = {POST}, consumes = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
@ResponseBody
public MyProto openProto(@RequestHeader(value = "Host") String host, @RequestBody
MyProto strBody, HttpServletRequest httpRequest
) throws InterruptedException {
return null;
}
问题是如果我让控制器这样,我会得到一个错误,因为我的网络服务不支持 application/octet-stream。
[main] 信息 org.eclipse.jetty.server.ServerConnector - 已启动 ServerConnector@73b05494{HTTP/1.1}{0.0.0.0:8180}
org.springframework.web.HttpMediaTypeNotSupportedException:不支持内容类型 'application/octet-stream'
在 org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:155) ...
如果我将 String 放入 @RequestBody 中,然后我进入我的方法,但它似乎没有使用转换器,并且无法使用 parseFrom 函数将字符串转换为 MyProto。
你有什么想法吗?
我真的找到了答案。
我们需要将 protobuf 视为一个 byte[]。这种类型已经有一个 HttpMessageConverter。因此 ResponseBody 应该是
public byte[] openProto(@RequestHeader(value = "Host") String host, @RequestBody
byte[] strBody, HttpServletRequest httpRequest
) throws InterruptedException {
return null;
}
我正在尝试使 Web 服务与 protobuf 和 json 一起工作。 问题在于我希望能够读取 inputStream 以构建我的原型(至少我没有看到另一种方式)。
我为 protobuf 创建了一个转换器:
public class ProtobufMessageConverter extends AbstractHttpMessageConverter<MyProto>{
@Override
protected boolean supports(Class<?> aClass) {
return MyProto.class.equals(aClass);
}
@Override
protected MyProto readInternal(Class<? extends MyProto> aClass, HttpInputMessage httpInputMessage)
throws IOException, HttpMessageNotReadableException {
return MyProto.parseFrom(httpInputMessage.getBody());
}
@Override
protected void writeInternal(MyProto proto, HttpOutputMessage httpOutputMessage)
throws IOException, HttpMessageNotWritableException {
OutputStream wr = httpOutputMessage.getBody();
wr.write(proto.toByteArray());
wr.close();
}
}
在我的 spring 配置中使用:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.test")
public class SpringMvcConfiguration extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {
httpMessageConverters.add(new ProtobufMessageConverter(new MediaType("application","octet-stream")));
addDefaultHttpMessageConverters(httpMessageConverters);
}
}
我的控制器:
@RequestMapping(value = "/proto", method = {POST}, consumes = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
@ResponseBody
public MyProto openProto(@RequestHeader(value = "Host") String host, @RequestBody
MyProto strBody, HttpServletRequest httpRequest
) throws InterruptedException {
return null;
}
问题是如果我让控制器这样,我会得到一个错误,因为我的网络服务不支持 application/octet-stream。
[main] 信息 org.eclipse.jetty.server.ServerConnector - 已启动 ServerConnector@73b05494{HTTP/1.1}{0.0.0.0:8180} org.springframework.web.HttpMediaTypeNotSupportedException:不支持内容类型 'application/octet-stream' 在 org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:155) ...
如果我将 String 放入 @RequestBody 中,然后我进入我的方法,但它似乎没有使用转换器,并且无法使用 parseFrom 函数将字符串转换为 MyProto。
你有什么想法吗?
我真的找到了答案。 我们需要将 protobuf 视为一个 byte[]。这种类型已经有一个 HttpMessageConverter。因此 ResponseBody 应该是
public byte[] openProto(@RequestHeader(value = "Host") String host, @RequestBody
byte[] strBody, HttpServletRequest httpRequest
) throws InterruptedException {
return null;
}