如何在返回服务端异常时保证output体不为空?
解决方案
要实现异常触发时同时返回非空output和错误信息,需要从异常携带业务数据、响应体结构支持、流程异常捕获三个方面调整代码:
1. 扩展自定义异常类,携带业务数据
修改MyException,添加字段存储需要返回的output内容,确保异常抛出时能带上已处理的业务数据:
public class MyException extends RuntimeException { private final Object businessData; // 新增构造器,传入错误信息和业务数据 public MyException(String message, Object businessData) { super(message); this.businessData = businessData; } // getter方法,用于后续取出业务数据 public Object getBusinessData() { return businessData; } }
2. 调整RestResponse结构,支持同时返回output和错误信息
确保RestResponse类能同时容纳output和errorMessages,新增对应构造器:
import java.util.Collections; import java.util.Map; public class RestResponse<T> { private T output; private Map<String, String> errorMessages; // 成功场景构造器 public RestResponse(T output) { this.output = output; this.errorMessages = Collections.emptyMap(); } // 异常场景构造器:同时传入业务数据和错误信息 public RestResponse(T output, String errorMessage) { this.output = output; this.errorMessages = Collections.singletonMap("EXCEPTION", errorMessage); } // 原错误场景构造器(保留兼容) public RestResponse(int errorCode, String message) { this.output = null; this.errorMessages = Collections.singletonMap("EXCEPTION", message); } // getter和setter方法 public T getOutput() { return output; } public void setOutput(T output) { this.output = output; } public Map<String, String> getErrorMessages() { return errorMessages; } public void setErrorMessages(Map<String, String> errorMessages) { this.errorMessages = errorMessages; } }
3. 修改业务处理流程,捕获异常时包装业务数据
在handle方法中,先预处理生成需要返回的output数据,调用服务时若抛出异常,则将output包装进MyException:
import reactor.util.function.Tuples; private Mono<Object> handle(ServerRequest request) { String pathParam = request.pathVariable("pathParam"); Long id = Long.parseLong(request.pathVariable("id")); return request.bodyToMono(Object.class) // 先构建要返回的output对象(根据实际业务逻辑生成) .map(body -> { // 示例:生成包含a、b字段的业务对象 Map<String, String> output = new HashMap<>(); output.put("a", "string"); output.put("b", "string"); // 返回业务数据和请求体的元组 return Tuples.of(output, body); }) .flatMap(tuple -> service.s(tuple.getT2(), pathParam, id) // 服务调用成功时,返回预处理的output .thenReturn(tuple.getT1()) // 服务调用异常时,包装output到MyException .onErrorMap(throwable -> new MyException(throwable.getMessage(), tuple.getT1())) ); }
4. 更新异常处理方法,构造包含output的响应
修改CommonHandler中的onConflictException方法,从MyException中取出业务数据,构造符合期望的响应体:
protected Mono<ServerResponse> onConflictException(MyException e) { // 从异常中取出业务数据 Object businessData = e.getBusinessData(); // 返回包含非空output和错误信息的响应 return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR) .bodyValue(new RestResponse<>(businessData, e.getMessage())); }
验证效果
调整完成后,当服务抛出MyException时,返回的响应体将同时包含非空的output和错误信息:
{ "output": { "a":"string", "b":"string" }, "errorMessages": { "EXCEPTION": "Errors string" } }
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

