如何使用Spring REST消耗protobuf参数?

Ada*_*old 5 spring protocol-buffers spring-restcontroller

我正在尝试将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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的测试看起来像这样:

@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);

        // ...

    }
}
Run Code Online (Sandbox Code Playgroud)

我确定它是参数的东西,因为如果我创建一个不采用protobuf参数但返回一个的变体,它只是工作正常.我尝试调试控制器代码,但执行没有到达方法所以问题可能在其他地方.如何正确地参数化此REST方法?

小智 0

这是完整的答案

@SpringBootApplication
public class JavaConnectorApplication {

    public static void main(String[] args) {
        SpringApplication.run(JavaConnectorApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您需要提供正确的配置。

 @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();
        }

    }
Run Code Online (Sandbox Code Playgroud)

最后是你的 RestController。

@RestController
public class TestTaskEndpoint {

    @PostMapping(value = "/testTask")
    TestTaskComplete processTestTask(@RequestBody TestTask testTask) {
        // TestTask is a generated protobuf class
        return generateResult(testTask);
    }
}
Run Code Online (Sandbox Code Playgroud)

@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());

    }
}
Run Code Online (Sandbox Code Playgroud)