Jerry's Blog

Recording what I learned everyday

View on GitHub


4 May 2019

Spring(9)----Standardize Response Body

by Jerry Zhang

#Tip of the Day:



Why standardize?

What’s the problem if we return the data directly to the frontend?

If our program has an error, the response will be rendered by Spring default page, which is the famous “Whitelabel Error Page”.

For frontend developer, they don’t know what’s the problem and what should be displayed to the user.

We should return a meaningful error information

Step 1: Standardize Response body

Response body should be formatted as “status + data”. We create a new class called CommonReturnType:

public class CommonReturnType {

    private String status;
    private Object data;

    public static CommonReturnType create(Object result){
        return CommonReturnType.create(result, "success");
    }

    private static CommonReturnType create(Object result, String status) {
        CommonReturnType type = new CommonReturnType();
        type.setStatus(status);
        type.setData(result);
        return type;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

The status should always be “200”, which means success, when the service handled the request successfully.

If there exists any error about business logic, we should return a proper error information.

Step 2: How to use this return type:

In our controller methods, we do not return the data directly, instead, we return a CommonReturnType. The original response body is inside the CommonReturnType.

@RequestMapping("/get")
@ResponseBody
public CommonReturnType getUser(@RequestParam(name = "id") Integer id){

    //Using service, retrieve user object and return to frontend
    UserModel userModel = userService.getUserById(id);
    UserVO userVO = convertFromModel(userModel);
    return CommonReturnType.create(userVO);
}

We should be able to get a result like this:

responsebody

Handle error exceptions

The example above is just the case when we get a success message. What if we got a fail result?

In the failed case, we want to return a status “fail” and a data with error code and error message.

Define errors

We can define a common error interface. Then we can define an enum class and an exception class. Then we can throw a new exception in the controller.

Use Spring ExceptionHandler

public class BaseController {
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Object handlerException(HttpServletRequest request, Exception ex){
        Map<String, Object> responseData = new HashMap<>();
        if (ex instanceof BusinessException) {
            BusinessException businessException = (BusinessException)ex;
            responseData.put("errCode", businessException.getErrCode());
            responseData.put("errMsg", businessException.getErrMsg());
        }else {
            responseData.put("errCode", EmBusinessError.UNKNOWN_ERROR.getErrCode());
            responseData.put("errMsg", EmBusinessError.UNKNOWN_ERROR.getErrMsg());
        }
        return CommonReturnType.create(responseData, "fail");
    }
}
tags: Java, - Spring, - response, - error