Java Spring MVC:如何在 ResponseEntity 主体中返回不同的类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19710710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:35:23  来源:igfitidea点击:

Spring MVC: How to return different type in ResponseEntity body

javaspringgenericsspring-mvc

提问by dnang

In my request handler I want to do some validation and based on the outcome of validation check I will return different response (success/error). So I create a abstract class for the response object and make 2 subclasses for failure case and successful case. The code looks something like this, but it doesn't compile, complaining that errorResponse and successResponse cannot be converted to AbstractResponse.

在我的请求处理程序中,我想做一些验证,并根据验证检查的结果,我将返回不同的响应(成功/错误)。所以我为响应对象创建了一个抽象类,并为失败案例和成功案例创建了 2 个子类。代码看起来像这样,但它不能编译,抱怨 errorResponse 和 successResponse 无法转换为 AbstractResponse。

I'm quite new to Java Generic and Spring MVC so I don't know of a simple way to solve this.

我对 Java Generic 和 Spring MVC 很陌生,所以我不知道解决这个问题的简单方法。

@ResponseBody ResponseEntity<AbstractResponse> createUser(@RequestBody String requestBody) {
    if(!valid(requestBody) {
        ErrorResponse errResponse = new ErrorResponse();
        //populate with error information
        return new ResponseEntity<> (errResponse, HTTPStatus.BAD_REQUEST);
    }
    createUser();
    CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
    // populate with more info
    return new ResponseEntity<> (successResponse, HTTPSatus.OK);
}

采纳答案by gadget

There are two problems here:

这里有两个问题:

  • your return type has to be changed to match the two response subclasses ResponseEntity<? extends AbstractResponse>
  • when you instantiate your ResponseEntity you cannot use the simplified <> syntax you have to specify which response class you are going to use new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);

    @ResponseBody ResponseEntity<? extends AbstractResponse> createUser(@RequestBody String requestBody) {
        if(!valid(requestBody) {
            ErrorResponse errResponse = new ErrorResponse();
            //populate with error information
            return new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);
        }
        createUser();
        CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
        // populate with more info
        return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK);
    }
    
  • 您的返回类型必须更改以匹配两个响应子类 ResponseEntity<? extends AbstractResponse>
  • 当您实例化 ResponseEntity 时,您不能使用简化的 <> 语法,您必须指定要使用的响应类 new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);

    @ResponseBody ResponseEntity<? extends AbstractResponse> createUser(@RequestBody String requestBody) {
        if(!valid(requestBody) {
            ErrorResponse errResponse = new ErrorResponse();
            //populate with error information
            return new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);
        }
        createUser();
        CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
        // populate with more info
        return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK);
    }
    

回答by Ruben

Another approach would be using error handlers

另一种方法是使用错误处理程序

@ResponseBody ResponseEntity<CreateUserSuccessResponse> createUser(@RequestBody String requestBody) throws UserCreationException {
    if(!valid(requestBody) {
        throw new UserCreationException(/* ... */)
    }
    createUser();
    CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
    // populate with more info
    return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK);
}

public static class UserCreationException extends Exception {
    // define error information here
}

@ExceptionHandler(UserCreationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handle(UserCreationException e) {
    ErrorResponse errResponse = new ErrorResponse();
    //populate with error information from the exception
    return errResponse;
}

This approach enables the possibility of returning any kind of object, so an abstract super class for the success case and the error case (or even cases) is no longer necessary.

这种方法可以返回任何类型的对象,因此不再需要用于成功案例和错误案例(甚至案例)的抽象超类。