template postforobject error code catch rest spring-mvc http-status-code-401 resttemplate

postforobject - Spring RestTemplate invocando el servicio web con errores y analiza el código de estado



resttemplate get status code (5)

Diseñé un servicio web para realizar una tarea si los parámetros de solicitud son correctos, o devuelvo el código de estado HTTP 401 no autorizado si los parámetros de solicitud son incorrectos o están vacíos.

Estoy usando RestTemplate para realizar una prueba y puedo verificar el estado de HTTP 200 OK si el servicio web responde con éxito. Sin embargo, no puedo probar el error HTTP 401 porque RestTemplate arroja una excepción.

Mi método de prueba es

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

El registro de excepciones es

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)

¿Cómo puedo probar si el servicio web responde con un código de estado HTTP 401?


Como alternativa a la solución presentada por nilesh, también podría usar la clase de primavera DefaultResponseErrorHandler. También necesita superar su método hasError (HttpStatus) para que no arroje ninguna excepción sobre el resultado no exitoso.

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


Debe implementar ResponseErrorHandler para interceptar el código de respuesta, el cuerpo y el encabezado cuando obtiene códigos de respuesta que no son 2xx del servicio utilizando la plantilla de descanso. Copie toda la información que necesita, adjúntela a su excepción personalizada y tírela para que pueda verla en su prueba.

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

Ahora lo que debe hacer en su prueba es configurar este ResponseErrorHandler en RestTemplate,

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


Desde Spring 4.3, hay una RestClientResponseException que contiene datos de respuesta HTTP reales, como el código de estado, el cuerpo de respuesta y los encabezados. Y puedes atraparlo.

RestClientResponseException Java Doc


En mi servicio de descanso capturo HttpStatusCodeException lugar de Exception ya que HttpStatusCodeException tiene un método para obtener el código de estado

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


Puedes usar spring-test. Es mucho más fácil:

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