我正在尝试将protobuf参数传递给REST端点,但我得到了
org.springframework.web.client.HttpServerErrorException:500 null
每次我尝试。我现在拥有的是这样的:
@RestController
public class TestTaskEndpoint {
@PostMapping(value = "/testTask", consumes = "application/x-protobuf", produces = "application/x-protobuf")
TestTaskComplete processTestTask(TestTask testTask) {
// TestTask is a generated protobuf class
return generateResult(testTask);
}
}
@Configuration
public class AppConfiguration {
@Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
@SpringBootApplication
public class JavaConnectorApplication {
public static void main(String[] args) {
SpringApplication.run(JavaConnectorApplication.class, args);
}
}
我的测试看起来像这样:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class JavaConnectorApplicationTest {
@Configuration
public static class RestClientConfiguration {
@Bean
RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
return new RestTemplate(Arrays.asList(hmc));
}
@Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
@Autowired
private RestTemplate restTemplate;
private int port = 8081;
@Test
public void contextLoaded() {
TestTask testTask = generateTestTask();
final String url = "http://127.0.0.1:" + port + "/testTask/";
ResponseEntity<TestTaskComplete> customer = restTemplate.postForEntity(url, testTask, TestTaskComplete.class);
// ...
}
}
我确信它是带参数的东西,因为如果我创建一个不采用protobuf参数但返回一个的变体,它就可以正常工作了。我尝试调试控制器代码,但执行没有到达方法所以问题可能在其他地方。如何正确地参数化此REST方法?
答案 0 :(得分:0)
这是完整的答案
@SpringBootApplication
public class JavaConnectorApplication {
public static void main(String[] args) {
SpringApplication.run(JavaConnectorApplication.class, args);
}
}
然后您需要提供正确的配置。
@Configuration
public class AppConfiguration {
//You need to add in this list all the messageConverters you will use
@Bean
RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
return new RestTemplate(Arrays.asList(hmc,smc));
}
@Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
最后是你的RestController。
@RestController
public class TestTaskEndpoint {
@PostMapping(value = "/testTask")
TestTaskComplete processTestTask(@RequestBody TestTask testTask) {
// TestTask is a generated protobuf class
return generateResult(testTask);
}
}
@RequestBody注释:请求的主体通过HttpMessageConverter(您已定义)传递,以根据请求的内容类型解析方法参数
你的考试班:
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class JavaConnectorApplicationTest {
@Autowired
private RestTemplate restTemplate;
private int port = 8081;
@Test
public void contextLoaded() {
TestTask testTask = generateTestTask();
final String url = "http://127.0.0.1:" + port + "/testTask/";
ResponseEntity<TestTaskComplete> customer = restTemplate.postForEntity(url, testTask, TestTaskComplete.class);
// Assert.assertEquals("dummyData", customer.getBody().getDummyData());
}
}
答案 1 :(得分:0)
这是我的第一个堆栈溢出答案,但我在通过 http 和 spring 搜索带有 protobuf 的工作示例时感到非常沮丧。
来自 Jorge 的答案 https://stackoverflow.com/a/44592469/15705964 几乎是正确的。 就像评论中提到的:“这本身是行不通的。你至少需要在某处添加一个转换器。”
这样做:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
ProtobufHttpMessageConverter protobufHttpMessageConverter;
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(protobufHttpMessageConverter);
}
}
ProtobufHttpMessageConverter 将自动完成他的工作并将对象添加到您的控制器方法中
@RestController
public class ProtobufController {
@PostMapping(consumes = "application/x-protobuf", produces = "application/x-protobuf")
public ResponseEntity<TestMessage.Response> handlePost(@RequestBody TestMessage.Request protobuf) {
TestMessage.Response response = TestMessage.Response.newBuilder().setQuery("This is a protobuf server Response")
.build();
return ResponseEntity.ok(response);
}
发送和接收休息的工作示例看看:https://github.com/Chriz42/spring-boot_protobuf_example