我的代码如下。
我希望根据状态代码获取不同的错误消息,如果成功则应该返回对象.. 如何从一种方法返回这种不同的数据类型?
public EstimateTimeResult getEstimateTime(@RequestBody EstimateTimeCall estimateTimeCall,@PathVariable("empid") Long empid) throws IOException{
String URL=baseApi+"/estimates/time";
if(estimateTimeCall.getProduct_id().isEmpty() || estimateTimeCall.getProduct_id()==null || estimateTimeCall.getProduct_id()==""){
URL+="?start_latitude="+estimateTimeCall.getStart_latitude().toString()+"&start_longitude="+estimateTimeCall.getStart_longitude().toString();
}else{
URL+="?start_latitude="+estimateTimeCall.getStart_latitude().toString()+"&start_longitude="+estimateTimeCall.getStart_longitude().toString()+"&product_id="+estimateTimeCall.getProduct_id();
}
//Header Set
HttpHeaders requestHeaders=getHeader(empid);
//Do Request
HttpEntity requestEntity=new HttpEntity(requestHeaders);
ResponseEntity<EstimateTimeResult> response=restTemplate.exchange(URL,HttpMethod.GET,requestEntity,EstimateTimeResult.class);
org.springframework.http.HttpStatus statusCode=response.getStatusCode();
if(statusCode.value()==422){
return "Required start latitude,longitude";
}
return response.getBody();
}
答案 0 :(得分:5)
简单:在Java中不可能(除非您将返回类型更改为Object,但这是非常糟糕的做法)。但是,&#34;不推荐&#34;将是更好的术语。
当然,你可以做这样的事情
class RequestResult {
static enum Result { PASS, FAIL };
private Whatever dataForPass;
private SomethingElse dataForFail;
Whatever get(){
return get((dataForFail)->throw new RequestError(dataForFail));
}
Whatever get(ErrorHandler handler){
if(dataForFail != null){
return handler.handle(dataForFail);
}
return dataForPass;
}
}
interface ErrorHandler{
Whatever handle(SomethingElse dataForFail) throws RequestError;
}
class RequestError extends RuntimeException{
SomethingElse data;
RequestError(SomethingElse data){
this.data=data;
}
}
然后您可以让RequestResult
处理如何获取Whatever
/ SomethingElse
数据,例如:
Whatever data = result.get((dataForFail) -> ...);
//or throws a RequestError if `SomethingElse` presented.
Whatever data = result.get();
然后创建这样一个对象;并根据具有所需数据的对象的实际结果设置。通过这样做,该方法的返回类型可以是RequestResult;你可以用它来传递和失败的请求。但这不是标准做法&#34;。
相反:您只在方法通过时返回一些内容。否则,您将抛出一个适当的异常,其中包含调用者需要提供有用错误消息的信息。
换句话说:你应该清楚地分开&#34; happy&#34;和不快乐的#34;路径。在Java中,你可以通过在出现问题时抛出异常来做到这一点。
答案 1 :(得分:1)
声称这在Java中是不可能的:虽然字面意思是不可能的,但是存在安全地执行此操作的库,受到来自其他编程语言的相同安全接口的启发。
我的快速浏览中最有希望的一个是@palatable's lambda,它将这个想法定义为:
public abstract class Either<L, R> {
private Either () {}
// how you make these
public static <L, R> Either<L, R> left(L l) { return new Left<>(l); }
public static <L, R> Either<L, R> right(R r) { return new Right<>(r); }
// how to use these
public abstract <V> V match(Function<? super L, ? extends V> leftFn,
Function<? super R, ? extends V> rightFn);
/* ~ some convenience methods to have a common interface to handle these things ~ */
// the actual classes
private static final class Left<L, R> extends Either<L, R> {
private final L l;
private Left(L l) {
this.l = l;
}
@Override
public <V> V match(Function<? super L, ? extends V> leftFn,
Function<? super R, ? extends V> rightFn) {
return leftFn.apply(l);
}
/* some other functions to get .equals() working right etc. */
}
// same for Right but with "R" swapped for "L"
}
定义一次后,您可以将实际的返回类型设置为Either <String, ResponseBody>
,然后可以return Either.left("hey, it's a string")
或return Either.right(response.getBody())
,然后您可以将这两种类型作为数据处理。
正如许多其他人所注意到的,处理Either <String, x>
类型的另一种方法是作为例外,它打破了正常的应用程序逻辑流程;你甚至可以定义一个更普遍的例外。但请记住,这将跳过您可能想要为这两者做的任何常见逻辑。您需要决定在您想要对响应正文做什么与错误String
之间是否存在任何共享应用程序逻辑,或者您是否希望拥有此类goto
}语句,直接跳转到指定的catch
块。对于不同的应用,这些答案可能不同。
答案 2 :(得分:0)
我认为您的问题中的这个应该是JAX-RS REST服务。
所以我想要表明我做这些事情的方式,我不能说是正确的要么完美。
在REST服务中,我返回一个像这样的对象
class APIResponse {
private Object content = null;
private Integer code = null;
private String message = null;
... getter, setter and what else
}
类APIResponse
是REST端点返回的公共对象:
public Response questionIdGet(String id, SecurityContext securityContext)
{
StatusCode sc;
try {
sc = new APIResponse().content(surveyBuilder.getQuestionById(id)).code(200);
return Response.ok()
.entity(sc)
.build();
} catch (Exception e) {
return Response.status(500)
.entity(new APIResponse().content(e).code(200).message(e.getMessage()))
.build();
}
}
通过这种方式,您的REST客户端会收到一个公共对象,他们知道在哪里找到内容{ "content" : object }
并检查其是否有效{ "status" : 200, "message" : "error..." }
。
答案 3 :(得分:0)
将其包装到一个处理两者的对象中,或者为错误状态抛出异常并处理它。
毕竟422是你的错误条件,所以抛出异常