使用Spring Rest Template处理响应多变的REST服务
我来帮你搞定这个Spring RestTemplate的问题!这种“成功时无返回、重复操作时有JSON响应”的场景确实有点棘手,不过有两个实用的方案可以完美解决:
方案一:用
exchange()方法灵活处理响应 RestTemplate的exchange()方法是最灵活的请求方式,能让我们精准控制请求和响应的处理逻辑,刚好适配这种“有时空响应、有时有JSON”的情况。
假设你的失效会话接口是DELETE请求,成功时返回204 No Content,会话已失效时返回409 Conflict(你可以根据实际状态码调整),代码示例如下:
RestTemplate restTemplate = new RestTemplate(); String invalidateUrl = "http://your-api-domain/api/invalidate-session"; try { // 用Void.class表示我们期望空响应体,避免204时抛出异常 ResponseEntity<Void> response = restTemplate.exchange( invalidateUrl, HttpMethod.DELETE, null, // 不需要请求体就传null Void.class ); if (response.getStatusCode() == HttpStatus.NO_CONTENT) { // 会话成功失效,执行你的业务逻辑 System.out.println("会话已成功失效"); } } catch (HttpClientErrorException e) { if (e.getStatusCode() == HttpStatus.CONFLICT) { // 解析已失效时返回的JSON响应 String errorJson = e.getResponseBodyAsString(); // 用ObjectMapper转成你自定义的错误DTO ObjectMapper mapper = new ObjectMapper(); SessionInvalidationError errorDto = mapper.readValue(errorJson, SessionInvalidationError.class); // 处理会话已失效的逻辑 System.out.println("会话已经处于失效状态:" + errorDto.getErrorMessage()); } else { // 其他HTTP错误直接抛出,或者自定义处理 throw e; } }
这个方案的好处是简单直接,针对单个端点处理很方便,不用额外配置。
方案二:自定义
ResponseErrorHandler统一处理 如果你的项目里有多个类似的接口,都需要处理“空响应+特定错误码返回JSON”的情况,那自定义一个全局的错误处理器会更高效。
首先写一个自定义的ErrorHandler:
public class SessionInvalidationErrorHandler extends DefaultResponseErrorHandler { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public boolean hasError(ClientHttpResponse response) throws IOException { HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode()); // 我们把409(会话已失效)排除在"错误"之外,不让RestTemplate自动抛出异常 return statusCode != null && (statusCode.is4xxClientError() && statusCode != HttpStatus.CONFLICT) || statusCode.is5xxServerError(); } // 专门处理会话已失效的方法 public SessionInvalidationError parseInvalidSessionError(ClientHttpResponse response) throws IOException { return objectMapper.readValue(response.getBody(), SessionInvalidationError.class); } }
然后在使用RestTemplate时配置这个处理器,并手动处理响应:
RestTemplate restTemplate = new RestTemplate(); SessionInvalidationErrorHandler customErrorHandler = new SessionInvalidationErrorHandler(); restTemplate.setErrorHandler(customErrorHandler); String invalidateUrl = "http://your-api-domain/api/invalidate-session"; // 手动创建请求并执行,这样能直接拿到响应对象 try (ClientHttpResponse response = restTemplate.getRequestFactory() .createRequest(URI.create(invalidateUrl), HttpMethod.DELETE) .execute()) { if (response.getStatusCode() == HttpStatus.NO_CONTENT) { System.out.println("会话成功失效"); } else if (response.getStatusCode() == HttpStatus.CONFLICT) { SessionInvalidationError errorDto = customErrorHandler.parseInvalidSessionError(response); System.out.println("会话已失效:" + errorDto.getErrorMessage()); } else { // 交给自定义处理器处理其他错误 customErrorHandler.handleError(response); } } catch (IOException e) { // 处理IO层面的异常 e.printStackTrace(); }
这个方案能让你在全局统一处理这类场景,避免重复写try-catch逻辑,适合多个接口复用的情况。
小提示
记得根据你的实际接口调整状态码(比如有的接口可能用400表示会话已失效),还有自定义的错误DTO要和接口返回的JSON结构对应上哦!
内容的提问来源于stack exchange,提问作者user1455410
相关产品推荐
相关产品推荐

