簡體   English   中英

Spring Boot Rest Controller:返回默認的Error JSON

[英]Spring Boot Rest Controller: Return default Error JSON

在我的API中,我喜歡保護用戶詳細信息端點,以便普通登錄用戶只能訪問其用戶配置文件。 因此我正在編寫控制器:

@RequestMapping(value = URL_USER + "/{id}", method = RequestMethod.GET)
@ResponseBody
public PersistentEntityResource get(PersistentEntityResourceAssembler persistentEntityResourceAssembler, @PathVariable Long id) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    ApplicationUser loggedInUser = applicationUserService.findByUsername(authentication.getName());
    ApplicationUser applicationUser = applicationUserService.findById(id);

    if (applicationUser.getId().equals(loggedInUser.getId())) {
        return persistentEntityResourceAssembler.toFullResource(applicationUser);
    }

    throw new IllegalAccessException();
} 

而不是引發導致InternalServerExcetption的異常,我喜歡返回默認的spring引導錯誤json,如下所示:

{
    "timestamp": "2019-05-08T11:42:23.064+0000",
    "status": 403,
    "error": "Forbidden",
    "message": "Access Denied",
    "path": "/user/2"
}

我會優先考慮一個解決方案,對於像404這樣的其他Erros也是如此。實現這一目標的最簡單方法是什么?

您可以使用以下方法

public class FooController{

    //...
    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public String handleException() {
        return "the intended body";
    }
}

或者,您可以使用@ControllerAdvice將此邏輯作為Global Exceptions Handler

@ControllerAdvice
public class RestResponseEntityExceptionHandler
        extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value
            = { IllegalArgumentException.class, IllegalStateException.class })
    protected ResponseEntity<Object> handleConflict(
            RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse,
                new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

經過一番研究后,我找到了一個看起來非常優雅的解

RestController方法如下所示:

@RequestMapping(value = URL_USER + "/{id}", method = RequestMethod.GET)
@ResponseBody
public PersistentEntityResource get(PersistentEntityResourceAssembler persistentEntityResourceAssembler, @PathVariable Long id) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    ApplicationUser loggedInUser = applicationUserService.findByUsername(authentication.getName());
    ApplicationUser applicationUser = applicationUserService.findById(id);

    if (applicationUser.getId().equals(loggedInUser.getId())) {
        return persistentEntityResourceAssembler.toFullResource(applicationUser);
    }

    throw new ForbiddenRequestException("Access not allowed");
}

另外我已經實現了類ForbiddenRequestException

@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class ForbiddenRequestException extends RuntimeException {
    public ForbiddenRequestException(String message) {
        super(message);
    }
}

至少要通過在屬性中設置server.error.include-stacktrace=never來從JSON中刪除trace ,這可能不太理想,但我認為在生產中你應該這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM