當我從 JUnit 測驗用例向 Rest Service 發送 GET 請求時,我收到 400 Bad Request。我的請求正文應該是 text/plain ( Content-Type: text/plain ),回應應該是 Employee 型別的 ResponseEntity。當我使用 Postman 呼叫請求時,我沒有收到任何錯誤,但是我無法使用 Spring Web Client 方法使其通過。
我有一個 POST REQUEST 示例,其中幾乎相似的測驗實作通過,不同之處在于,在請求正文中我傳遞了 Employee 的整個物件,而在失敗的測驗中是文本/純文本。(最后添加)
我試圖理解為什么它不起作用,但我無法弄清楚。我還嘗試使用 getForObject、getForEntity 更改交換方法,但沒有成功。
完整網址:http://localhost:8080/employee/find/lastName/
LE:IntelliJ 高亮顯示 .exchange 方法讓我很生氣,并告訴我該方法會以 400 回應。
如果我遺漏了什么,請詢問任何其他詳細資訊。請幫助我解決問題。謝謝 !:)
控制器
@RequestMapping (value = "/find/lastName", headers="Content-Type=text/plain", method = RequestMethod.GET)
public ResponseEntity<Employee> findEmployeeByLastName(@RequestBody String lastName) {
return EmployeeService.getEmployeeByLastName(lastName);
}
服務
public static ResponseEntity<Employee> getEmployeeByLastName(String lastName) {
return employees
.stream()
.filter(employee -> employee.getLastName().equals(lastName))
.findFirst()
.map(employee -> new ResponseEntity<>(employee, HttpStatus.OK))
.orElseThrow(() -> new ExmployeeResourceException("Not Found"));
}
JUnit 測驗
@Test
public void ShouldReturnEmployeeByUsingLastName() {
RestTemplate restTemplate = new RestTemplate();
String employeeLastName = "Doe";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<String> request = new HttpEntity<>(employeeLastName, headers);
ResponseEntity<Employee> responseEntity =
restTemplate.exchange(
HOSTNAME ENDPOINT "find/lastName/",
HttpMethod.GET,
request,
Employee.class
);
}
錯誤日志
22:12:28.619 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [Doe] as "text/plain" using [org.springframework.http.converter.StringHttpMessageConverter@48075da3]
22:12:28.764 [main] DEBUG org.springframework.web.client.RestTemplate - GET request for "http://localhost:8080/employee/find/lastName/" resulted in 400 (null); invoking error handler
org.springframework.web.client.HttpClientErrorException: 400 null at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at com.endava.rest.EmployeeTests.ShouldReturnEmployeeByUsingLastName(EmployeeTests.java:90)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
通過的測驗示例
@Test
public void ShouldBeAbleToCreateAnEmployee() {
RestTemplate restTemplate = new RestTemplate();
Integer id = 3;
String firstName = "Ionut";
String lastName = "Popescu";
Employee newEmployee = new Employee(id, firstName, lastName);
HttpEntity<Employee> httpEntity = new HttpEntity<>(newEmployee);
ResponseEntity<Employee> responseEntity =
restTemplate.exchange(
HOSTNAME ENDPOINT,
HttpMethod.POST,
httpEntity,
Employee.class
);
}
uj5u.com熱心網友回復:
我的請求有一個正文,它是一個文本(字串),這就是我添加 Content-Type 標頭的原因。
RestTemplate客戶端不支持GET請求中的物體。GET鑒于這種 API 很少見,這在客戶端中很常見,因此缺乏對 body in 的支持。
RestTemplate有關具體的更多資訊:
我假設您使用的是
RestTemplate帶有默認值的 aClientHttpRequestFactory。在這種情況下,JDKHttpURLConnection是底層 HTTP 客戶端。HttpURLConnection不為 GET 請求發送請求正文;我已經使用 Wireshark 驗證了這一點。
如果你真的堅持RestTemplate,你的選擇是使用不同的ClientHttpRequestFactory。例如:
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
class HttpComponentsClientHttpRequestFactoryForGetWithBody extends HttpComponentsClientHttpRequestFactory {
private static final class HttpGetRequestWithBody extends HttpEntityEnclosingRequestBase {
public HttpGetRequestWithBody(URI uri) { super.setURI(uri); }
@Override public String getMethod() { return HttpMethod.GET.name(); }
}
@Override
protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
if (HttpMethod.GET.equals(httpMethod)) {
return new HttpGetRequestWithBody(uri);
}
return super.createHttpUriRequest(httpMethod, uri);
}
}
用法:
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactoryForGetWithBody());
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/436295.html
上一篇:Numpy:獲取陣列中邊界的索引,其中邊界的開始總是以特定的數字開始;特定數量的無邊界
下一篇:發布成功但回應是前端錯誤
