junit 如何实现通过RestTemplate执行的PATCH?

elcex8rz  于 2023-02-23  发布在  其他
关注(0)|答案(6)|浏览(210)

我正在编写JUnit测试,通过RestTemplate调用我的应用程序。我已经成功地实现了GET、POST和PUT,但是不能运行PATCH(尽管当客户端发送URL时它可以工作)。

RestTemplate restTemplate = new RestTemplate(); 
    ProductModel postModel = restTemplate.postForObject(TestBase.URL + URL, pModel, ProductModel.class);

但是当我试图调用restTemplate.patchForObject()(我在网上找到的)时,STS返回一个错误,说函数没有定义。

RestTemplate restTemplate = new RestTemplate(); 
    ResponseEntity<MessageModel> retval = restTemplate.exchange("http://localhost:8080/products/batchUpdateProductPositions", 
            HttpMethod.PATCH, new HttpEntity<ProductPositionListModel>(pps), MessageModel.class);

它可以编译,但是会给我一个错误:

I/O Error on PATCH request for "http://localhost:8080/products/batchUpdateProductPositions": Invalid HTTP method: PATCH

在应用程序中,我在Controller类中定义了以下操作:

@RequestMapping(value = "/batchUpdateProductPositions", method = RequestMethod.PATCH)
public MessageModel batchUpdatePosition(
        @RequestBody ProductPositionListModel productPositionList)
        throws Exception {
    try {
        return productService.batchUpdatePosition(productPositionList);
    } catch (Exception e) {

我在'try'块中的return语句上放置了一个断点,但是当我在调试状态下运行它时,它从来没有被触发过。
谁能告诉我哪里出错了?

uhry853o

uhry853o1#

默认情况下,RestTemplate使用标准JDK HttpURLConnection HTTP客户端发出请求。此客户端不支持PATCH方法。您可以通过客户端工厂配置RestTemplate以使用其他HTTP客户端,如HttpComponentsClientHttpRequestFactoryOkHttpClientHttpRequestFactory

HttpClient client = HttpClients.createDefault();
RestTemplate template= new RestTemplate();
template.setRequestFactory(new HttpComponentsClientHttpRequestFactory(client));

您还需要添加适当的依赖项,例如HTTP组件客户端中的org.apache.httpcomponents:httpclient:$version

ukdjmx9f

ukdjmx9f2#

我发现了一个与JUnit代码的其余部分保持一致的解决方案,使用postForObject(),您可以传入在这种情况下所需的HTTP方法:

MessageModel pModel = restTemplate.postForObject(TestBase.URL + URL + "/batchUpdateProductPositions?_method=patch", 
            pps, MessageModel.class);

运行正常。不知道有没有我没注意到的副作用。

agxfikkp

agxfikkp3#

对于使用RestTemplate执行PATCH请求,这对我很有效:

RestTemplate restTemplate = new RestTemplate();

HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectTimeout(timeout);
httpRequestFactory.setReadTimeout(timeout);

restTemplate.setRequestFactory(httpRequestFactory);

现在将这个restTemplate与exchange()一起使用。
必需依赖关系

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
zte4gxcn

zte4gxcn4#

试试这个:

import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
//...
RestTemplate rest = new RestTemplate(new HttpComponentsClientHttpRequestFactory())

//Now make the PATCH call using Exchange
ResponseEntity<Map<String, Object>> response = rest.exchange(api, HttpMethod.PATCH, request, responseType);

不要忘记将此添加到您的依赖项中:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.4.1</version>
 </dependency>
rbl8hiat

rbl8hiat5#

本解决方案

MessageModel pModel = restTemplate.postForObject(TestBase.URL + URL + "/batchUpdateProductPositions?_method=patch",pps, MessageModel.class);

如果您正在使用Post方法(@PostMapping),则非常有用。如果您希望使用Patch方法(@PatchMapping),请尝试以下操作:

restTemplate.patchForObject("http://localhost:8080/products/batchUpdateProductPositions", requestEntity, String.class);
a1o7rhls

a1o7rhls6#

WebClient提供了RestTemplate的现代替代方案,有效支持同步和异步以及流媒体场景。您可以使用WebClient实现这一点。
配置WebClient

@Configuration
public class WebConfig {
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

然后可以调用

//Constructor Injection 
public YourClassName(WebClient.Builder webClientBuilder) {
   this.webClientBuilder = webClientBuilder;
}

MessageModel response = webClientBuilder.build()
                .patch()
                .uri("http://localhost:8080/products/batchUpdateProductPositions")
                .contentType(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(MessageModel.class)
                .block();

pom.xml的依赖关系

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

相关问题