Spring RestTemplate invoking webservice with errors and analyze status code

最后都变了- 提交于 2019-11-28 03:50:01
nilesh

You need to implement ResponseErrorHandler in order to intercept response code, body, and header when you get non-2xx response codes from the service using rest template. Copy all the information you need, attach it to your custom exception and throw it so that you can catch it in your test.

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;
    }
}

Now what you need to do in your test is, set this ResponseErrorHandler in RestTemplate like,

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]"));
}

As an alternative to the solution presented by nilesh, you could also use spring class DefaultResponseErrorHandler. You also need to ovveride its hasError(HttpStatus) method so it does not throw exception on non-successful result.

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

In my rest service I catch HttpStatusCodeException instead of Exception since HttpStatusCodeException has a method for getting the status code

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

You can use spring-test. It's much easier:

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

Since Spring 4.3, There is a RestClientResponseException which contain actual HTTP response data, such as status code, response body and headers. And you can catch it.

RestClientResponseException Java Doc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!