如何使用 Post 方法测试在 Rest 服务上获取参数
How to test getting parameters on the Rest service using the Post method
我正在尝试使用 Post 方法测试获取处理请求的参数
@RestController
@RequestMapping("api")
public class InnerRestController {
…
@PostMapping("createList")
public ItemListId createList(@RequestParam String strListId,
@RequestParam String strDate) {
…
return null;
}
}
- 测试方法
变体 1
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class InnerRestControllerTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void innerCreatePublishList() {
String url = "http://localhost:" + this.port;
String uri = "/api/createList";
String listStr = "kl";
String strDate = "10:21";
URI uriToEndpoint = UriComponentsBuilder
.fromHttpUrl(url)
.path(uri)
.queryParam("strListId", listStr)
.queryParam("strDate ", strDate)
.build()
.encode()
.toUri();
ResponseEntity< ItemListId > listIdResponseEntity =
restTemplate.postForEntity(uri, uriToEndpoint, ItemListId.class);
}
}
变体 2
@Test
void createList() {
String uri = "/api/createList";
String listStr = "kl";
String strDate = "10:21";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(uri)
.queryParam("strListId", listStr)
.queryParam("strDate ", strDate);
Map<String, String> map = new HashMap<>();
map.put("strListId", listStr);//request parameters
map.put("strDate", strDate);
ResponseEntity< ItemListId > listIdResponseEntity =
restTemplate.postForEntity(uri, map, ItemListId.class);
}
Update_1
在我的项目中异常是这样处理的:
- dto
public final class ErrorResponseDto {
private String errorMsg;
private int status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
LocalDateTime timestamp;
...
- 处理程序
@RestControllerAdvice
public class ExceptionAdviceHandler {
@ExceptionHandler(value = PublishListException.class)
public ResponseEntity<ErrorResponseDto> handleGenericPublishListDublicateException(PublishListException e) {
ErrorResponseDto error = new ErrorResponseDto(e.getMessage());
error.setTimestamp(LocalDateTime.now());
error.setStatus((HttpStatus.CONFLICT.value()));
return new ResponseEntity<>(error, HttpStatus.CONFLICT);
}
}
在方法中,必要时,我抛出一个特定的异常...
.w.s.m.s.DefaultHandlerExceptionResolver : Resolved
[org.springframework.web.bind.MissingServletRequestParameterException:
Required String parameter 'strListId' is not present]
谁知道错误是什么。请说明您需要在此处添加什么以及为什么?
我们来看看 postEntity
的 declarations:
postForEntity(URI url, Object request, Class<T> responseType)
...
postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
如您所见,第一个参数是 URI
或 String with uriVariables
,但第二个参数始终是请求实体。
在您的第一个变体中,您将 uri
字符串作为 URI,然后将 uriToEndpoint
作为请求实体传递,假装它是请求对象。正确的解决方案是:
ResponseEntity<ItemListId> listIdResponseEntity =
restTemplate.postForEntity(uriToEndpoint, null, ItemListId.class);
处理您的意见。
如果服务器响应 HTTP 409,RestTemplate
将抛出您的 ErrorResponseDto
内容的异常。您可以捕获 RestClientResponseException
并反序列化存储在异常中的服务器响应。像这样:
try {
ResponseEntity<ItemListId> listIdResponseEntity =
restTemplate.postForEntity(uriToEndpoint, null,
ItemListId.class);
...
} catch(RestClientResponseException e) {
byte[] errorResponseDtoByteArray = e.getResponseBodyAsByteArray();
// Deserialize byte[] array using Jackson
}
我正在尝试使用 Post 方法测试获取处理请求的参数
@RestController
@RequestMapping("api")
public class InnerRestController {
…
@PostMapping("createList")
public ItemListId createList(@RequestParam String strListId,
@RequestParam String strDate) {
…
return null;
}
}
- 测试方法
变体 1
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class InnerRestControllerTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void innerCreatePublishList() {
String url = "http://localhost:" + this.port;
String uri = "/api/createList";
String listStr = "kl";
String strDate = "10:21";
URI uriToEndpoint = UriComponentsBuilder
.fromHttpUrl(url)
.path(uri)
.queryParam("strListId", listStr)
.queryParam("strDate ", strDate)
.build()
.encode()
.toUri();
ResponseEntity< ItemListId > listIdResponseEntity =
restTemplate.postForEntity(uri, uriToEndpoint, ItemListId.class);
}
}
变体 2
@Test
void createList() {
String uri = "/api/createList";
String listStr = "kl";
String strDate = "10:21";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(uri)
.queryParam("strListId", listStr)
.queryParam("strDate ", strDate);
Map<String, String> map = new HashMap<>();
map.put("strListId", listStr);//request parameters
map.put("strDate", strDate);
ResponseEntity< ItemListId > listIdResponseEntity =
restTemplate.postForEntity(uri, map, ItemListId.class);
}
Update_1
在我的项目中异常是这样处理的:
- dto
public final class ErrorResponseDto {
private String errorMsg;
private int status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
LocalDateTime timestamp;
...
- 处理程序
@RestControllerAdvice
public class ExceptionAdviceHandler {
@ExceptionHandler(value = PublishListException.class)
public ResponseEntity<ErrorResponseDto> handleGenericPublishListDublicateException(PublishListException e) {
ErrorResponseDto error = new ErrorResponseDto(e.getMessage());
error.setTimestamp(LocalDateTime.now());
error.setStatus((HttpStatus.CONFLICT.value()));
return new ResponseEntity<>(error, HttpStatus.CONFLICT);
}
}
在方法中,必要时,我抛出一个特定的异常...
.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'strListId' is not present]
谁知道错误是什么。请说明您需要在此处添加什么以及为什么?
我们来看看 postEntity
的 declarations:
postForEntity(URI url, Object request, Class<T> responseType)
...
postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
如您所见,第一个参数是 URI
或 String with uriVariables
,但第二个参数始终是请求实体。
在您的第一个变体中,您将 uri
字符串作为 URI,然后将 uriToEndpoint
作为请求实体传递,假装它是请求对象。正确的解决方案是:
ResponseEntity<ItemListId> listIdResponseEntity =
restTemplate.postForEntity(uriToEndpoint, null, ItemListId.class);
处理您的意见。
如果服务器响应 HTTP 409,RestTemplate
将抛出您的 ErrorResponseDto
内容的异常。您可以捕获 RestClientResponseException
并反序列化存储在异常中的服务器响应。像这样:
try {
ResponseEntity<ItemListId> listIdResponseEntity =
restTemplate.postForEntity(uriToEndpoint, null,
ItemListId.class);
...
} catch(RestClientResponseException e) {
byte[] errorResponseDtoByteArray = e.getResponseBodyAsByteArray();
// Deserialize byte[] array using Jackson
}