春天RestTemplate调用webservice的错误和分析状态代码(Spring RestTe

2019-07-21 14:26发布

我设计了一个Web服务,如果请求参数都OK执行任务,或返回401未经授权HTTP状态代码,如果请求参数是错误的或空。

我使用RestTemplate进行测试,我能够验证的HTTP 200 OK状态,如果Web服务成功回复。 不过,我无法测试HTTP 401错误,因为RestTemplate本身抛出异常。

我的测试方法是

@Test
public void testUnauthorized()
{
    Map<String, Object> params = new HashMap<String, Object>();
    ResponseEntity response = restTemplate.postForEntity(url, params, Map.class);
    Assert.assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
    Assert.assertNotNull(response.getBody());
}

异常日志

org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:533)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:489)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:447)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:318)

如何如果Web服务使用HTTP状态码401回复我可以测试?

Answer 1:

您需要实现ResponseErrorHandler为了拦截响应码,身体和头部,当你使用模板休息从服务中获得非2xx响应代码。 复制你需要的所有信息,将其连接到您的自定义异常,并把它使您可以在您的测试抓住它。

public class CustomResponseErrorHandler implements ResponseErrorHandler {

    private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();

    public boolean hasError(ClientHttpResponse response) throws IOException {
        return errorHandler.hasError(response);
    }

    public void handleError(ClientHttpResponse response) throws IOException {
        String theString = IOUtils.toString(response.getBody());
        CustomException exception = new CustomException();
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("code", response.getStatusCode().toString());
        properties.put("body", theString);
        properties.put("header", response.getHeaders());
        exception.setProperties(properties);
        throw exception;
    }
}

现在,您需要在您的测试做的是,在RestTemplate设置此ResponseErrorHandler像什么,

RestTemplate restclient = new RestTemplate();
restclient.setErrorHandler(new CustomResponseErrorHandler());
try {
    POJO pojo = restclient.getForObject(url, POJO.class); 
} catch (CustomException e) {
    Assert.isTrue(e.getProperties().get("body")
                    .equals("bad response"));
    Assert.isTrue(e.getProperties().get("code").equals("400"));
    Assert.isTrue(((HttpHeaders) e.getProperties().get("header"))
                    .get("fancyheader").toString().equals("[nilesh]"));
}


Answer 2:

作为替代由Nilesh制作提出的解决方案,你也可以使用Spring类DefaultResponseErrorHandler。 您还需要ovveride其hasError(的HTTPStatus)方法,因此不会引发非成功的结果异常。

restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
    protected boolean hasError(HttpStatus statusCode) {
        return false;
    }});


Answer 3:

在我休息的服务,我赶上HttpStatusCodeException而不是Exception ,因为HttpStatusCodeException有越来越状态码的方法

catch(HttpStatusCodeException e) {
    log.debug("Status Code", e.getStatusCode());
}


Answer 4:

你可以使用Spring测试。 这是很容易:

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:your-context.xml")
public class BasicControllerTest {

        @Autowired
        protected WebApplicationContext wac;
        protected MockMvc mockMvc;

        @Before
        public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
        }

        @Test
        public void testUnauthorized(){

        mockMvc.perform(MockMvcRequestBuilders
                            .post("your_url")
                            .param("name", "values")
        .andDo(MockMvcResultHandlers.print())
        .andExpect(MockMvcResultMatchers.status().isUnauthorized()
        .andExpect(MockMvcResultMatchers.content().string(Matchers.notNullValue()));
        }
}


Answer 5:

由于弹簧4.3,有一个RestClientResponseException其包含实际的HTTP响应数据,诸如状态码,响应身体和头。 你可以抓住它。

RestClientResponseException Java文档



文章来源: Spring RestTemplate invoking webservice with errors and analyze status code