-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add constants and handle exception in product (#69)
- Loading branch information
Showing
13 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
product/src/main/java/com/fjb/product/constants/ApiConstant.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.fjb.product.constants; | ||
|
||
public final class ApiConstant { | ||
public static final String CODE_200 = "200"; | ||
public static final String OK = "OK"; | ||
public static final String CODE_404 = "404"; | ||
public static final String NOT_FOUND = "NOT_FOUND"; | ||
public static final String CODE_201 = "201"; | ||
public static final String CREATED = "CREATED"; | ||
public static final String CODE_400 = "400"; | ||
public static final String BAD_REQUEST = "BAD_REQUEST"; | ||
public static final String CODE_204 = "204"; | ||
public static final String NO_CONTENT = "NO_CONTENT"; | ||
public static final String ACCESS_DENIED = "ACCESS_DENIED"; | ||
|
||
private ApiConstant() { | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
product/src/main/java/com/fjb/product/constants/MessageCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.fjb.product.constants; | ||
|
||
public final class MessageCode { | ||
public static final String PRODUCT_NOT_FOUND = "PRODUCT_NOT_FOUND"; | ||
public static final String NAME_ALREADY_EXISTED = "NAME_ALREADY_EXISTED"; | ||
public static final String REQUEST_INFORMATION_NOT_VALID = "REQUEST_INFORMATION_NOT_VALID"; | ||
|
||
private MessageCode() { | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
product/src/main/java/com/fjb/product/constants/PageableConstant.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.fjb.product.constants; | ||
|
||
public final class PageableConstant { | ||
public static final String DEFAULT_PAGE_SIZE = "10"; | ||
public static final String DEFAULT_PAGE_NUMBER = "0"; | ||
|
||
private PageableConstant() { | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
product/src/main/java/com/fjb/product/dto/response/ErrorVm.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.fjb.product.dto.response; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public record ErrorVm(String statusCode, String title, String detail, List<String> fieldErrors) { | ||
|
||
public ErrorVm(String statusCode, String title, String detail) { | ||
this(statusCode, title, detail, new ArrayList<>()); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
product/src/main/java/com/fjb/product/exception/AccessDeniedException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.fjb.product.exception; | ||
|
||
public class AccessDeniedException extends RuntimeException { | ||
public AccessDeniedException(final String message) { | ||
super(message); | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
product/src/main/java/com/fjb/product/exception/ApiExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package com.fjb.product.exception; | ||
|
||
import com.fjb.product.constants.MessageCode; | ||
import com.fjb.product.dto.response.ErrorVm; | ||
import jakarta.validation.ConstraintViolationException; | ||
import java.util.List; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.dao.DataIntegrityViolationException; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.MethodArgumentNotValidException; | ||
import org.springframework.web.bind.MissingServletRequestParameterException; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.context.request.ServletWebRequest; | ||
import org.springframework.web.context.request.WebRequest; | ||
|
||
@ControllerAdvice | ||
@Slf4j | ||
public class ApiExceptionHandler { | ||
private static final String ERROR_LOG_FORMAT = "Error: URI: {}, ErrorCode: {}, Message: {}"; | ||
|
||
@ExceptionHandler(NotFoundException.class) | ||
public ResponseEntity<ErrorVm> handleNotFoundException(NotFoundException ex, WebRequest request) { | ||
HttpStatus status = HttpStatus.NOT_FOUND; | ||
String message = ex.getMessage(); | ||
|
||
return buildErrorResponse(status, message, null, ex, request, status.value()); | ||
} | ||
|
||
@ExceptionHandler(MethodArgumentNotValidException.class) | ||
protected ResponseEntity<ErrorVm> handleMethodArgumentNotValid(MethodArgumentNotValidException ex) { | ||
|
||
HttpStatus status = HttpStatus.BAD_REQUEST; | ||
|
||
List<String> errors = ex.getBindingResult() | ||
.getFieldErrors() | ||
.stream() | ||
.map(error -> error.getField() + " " + error.getDefaultMessage()) | ||
.toList(); | ||
|
||
return buildErrorResponse(status, MessageCode.REQUEST_INFORMATION_NOT_VALID, errors, ex, null, status.value()); | ||
} | ||
|
||
@ExceptionHandler(Exception.class) | ||
protected ResponseEntity<ErrorVm> handleOtherException(Exception ex, WebRequest request) { | ||
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; | ||
String message = ex.getMessage(); | ||
|
||
return buildErrorResponse(status, message, null, ex, request, status.value()); | ||
} | ||
|
||
@ExceptionHandler(BadRequestException.class) | ||
public ResponseEntity<ErrorVm> handleBadRequestException(BadRequestException ex, WebRequest request) { | ||
return handleBadRequest(ex, request); | ||
} | ||
|
||
@ExceptionHandler({ConstraintViolationException.class}) | ||
public ResponseEntity<ErrorVm> handleConstraintViolation(ConstraintViolationException ex) { | ||
HttpStatus status = HttpStatus.BAD_REQUEST; | ||
|
||
List<String> errors = ex.getConstraintViolations().stream() | ||
.map(violation -> String.format("%s %s: %s", | ||
violation.getRootBeanClass().getName(), | ||
violation.getPropertyPath(), | ||
violation.getMessage())) | ||
.toList(); | ||
|
||
return buildErrorResponse(status, MessageCode.REQUEST_INFORMATION_NOT_VALID, errors, ex, null, status.value()); | ||
} | ||
|
||
@ExceptionHandler(DataIntegrityViolationException.class) | ||
public ResponseEntity<ErrorVm> handleDataIntegrityViolationException(DataIntegrityViolationException ex) { | ||
return handleBadRequest(ex, null); | ||
} | ||
|
||
@ExceptionHandler(DuplicatedException.class) | ||
protected ResponseEntity<ErrorVm> handleDuplicated(DuplicatedException ex) { | ||
return handleBadRequest(ex, null); | ||
} | ||
|
||
|
||
@ExceptionHandler(MissingServletRequestParameterException.class) | ||
protected ResponseEntity<ErrorVm> handleMissingParams(MissingServletRequestParameterException e) { | ||
return handleBadRequest(e, null); | ||
} | ||
|
||
|
||
@ExceptionHandler(AccessDeniedException.class) | ||
public ResponseEntity<ErrorVm> handleAccessDeniedException(AccessDeniedException ex, WebRequest request) { | ||
HttpStatus status = HttpStatus.FORBIDDEN; | ||
String message = ex.getMessage(); | ||
|
||
return buildErrorResponse(status, message, null, ex, request, status.value()); | ||
} | ||
|
||
private String getServletPath(WebRequest webRequest) { | ||
ServletWebRequest servletRequest = (ServletWebRequest) webRequest; | ||
return servletRequest.getRequest().getServletPath(); | ||
} | ||
|
||
private ResponseEntity<ErrorVm> handleBadRequest(Exception ex, WebRequest request) { | ||
HttpStatus status = HttpStatus.BAD_REQUEST; | ||
String message = ex.getMessage(); | ||
|
||
return buildErrorResponse(status, message, null, ex, request, status.value()); | ||
} | ||
|
||
private ResponseEntity<ErrorVm> buildErrorResponse(HttpStatus status, String message, List<String> errors, | ||
Exception ex, WebRequest request, int statusCode) { | ||
ErrorVm errorVm = | ||
new ErrorVm(status.toString(), status.getReasonPhrase(), message, errors); | ||
|
||
if (request != null) { | ||
log.error(ERROR_LOG_FORMAT, this.getServletPath(request), statusCode, message); | ||
} | ||
log.error(message, ex); | ||
return ResponseEntity.status(status).body(errorVm); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
product/src/main/java/com/fjb/product/exception/BadRequestException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.fjb.product.exception; | ||
|
||
|
||
import com.fjb.product.utils.MessagesUtils; | ||
|
||
public class BadRequestException extends RuntimeException { | ||
|
||
private final String message; | ||
|
||
public BadRequestException(String message) { | ||
this.message = MessagesUtils.getMessage(message); | ||
} | ||
|
||
public BadRequestException(String errorCode, Object... var2) { | ||
this.message = MessagesUtils.getMessage(errorCode, var2); | ||
} | ||
|
||
@Override | ||
public String getMessage() { | ||
return message; | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
product/src/main/java/com/fjb/product/exception/DuplicatedException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.fjb.product.exception; | ||
|
||
|
||
import com.fjb.product.utils.MessagesUtils; | ||
|
||
public class DuplicatedException extends RuntimeException { | ||
|
||
private final String message; | ||
|
||
public DuplicatedException(String errorCode, Object... var2) { | ||
this.message = MessagesUtils.getMessage(errorCode, var2); | ||
} | ||
|
||
@Override | ||
public String getMessage() { | ||
return message; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
product/src/main/java/com/fjb/product/exception/ForbiddenException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.fjb.product.exception; | ||
|
||
|
||
import com.fjb.product.utils.MessagesUtils; | ||
|
||
public class ForbiddenException extends RuntimeException { | ||
private final String message; | ||
|
||
public ForbiddenException(String errorCode, Object... var2) { | ||
this.message = MessagesUtils.getMessage(errorCode, var2); | ||
} | ||
|
||
@Override | ||
public String getMessage() { | ||
return message; | ||
} | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
product/src/main/java/com/fjb/product/exception/NotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.fjb.product.exception; | ||
|
||
|
||
import com.fjb.product.utils.MessagesUtils; | ||
|
||
public class NotFoundException extends RuntimeException { | ||
private final String message; | ||
|
||
public NotFoundException(String errorCode, Object... var2) { | ||
this.message = MessagesUtils.getMessage(errorCode, var2); | ||
} | ||
|
||
@Override | ||
public String getMessage() { | ||
return message; | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
product/src/main/java/com/fjb/product/utils/AuthenticationUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.fjb.product.utils; | ||
|
||
import com.fjb.product.constants.ApiConstant; | ||
import com.fjb.product.exception.AccessDeniedException; | ||
import org.springframework.security.authentication.AnonymousAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.oauth2.jwt.Jwt; | ||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; | ||
|
||
public final class AuthenticationUtils { | ||
|
||
private AuthenticationUtils() { | ||
} | ||
|
||
public static String extractUserId() { | ||
Authentication authentication = getAuthentication(); | ||
|
||
if (authentication instanceof AnonymousAuthenticationToken) { | ||
throw new AccessDeniedException(ApiConstant.ACCESS_DENIED); | ||
} | ||
|
||
JwtAuthenticationToken contextHolder = (JwtAuthenticationToken) authentication; | ||
|
||
return contextHolder.getToken().getSubject(); | ||
} | ||
|
||
public static String extractJwt() { | ||
return ((Jwt) getAuthentication().getPrincipal()).getTokenValue(); | ||
} | ||
|
||
public static Authentication getAuthentication() { | ||
return SecurityContextHolder.getContext().getAuthentication(); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
product/src/main/java/com/fjb/product/utils/MessagesUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.fjb.product.utils; | ||
|
||
import java.util.Locale; | ||
import java.util.MissingResourceException; | ||
import java.util.ResourceBundle; | ||
import org.slf4j.helpers.FormattingTuple; | ||
import org.slf4j.helpers.MessageFormatter; | ||
|
||
public class MessagesUtils { | ||
private static final ResourceBundle messageBundle = ResourceBundle.getBundle("messages.messages", | ||
Locale.getDefault()); | ||
|
||
private MessagesUtils() { | ||
} | ||
|
||
public static String getMessage(String errorCode, Object... var2) { | ||
String message; | ||
try { | ||
message = messageBundle.getString(errorCode); | ||
} catch (MissingResourceException ex) { | ||
message = errorCode; | ||
} | ||
FormattingTuple formattingTuple = MessageFormatter.arrayFormat(message, var2); | ||
return formattingTuple.getMessage(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
PRODUCT_NOT_FOUND=The product {} is not found | ||
NAME_ALREADY_EXISTED=The name {} is already existed | ||
ACCESS_DENIED=Access denied | ||
NO_CONTENT=No content | ||
BAD_REQUEST=Bad request | ||
CREATED=Created | ||
NOT_FOUND=Not found | ||
REQUEST_INFORMATION_NOT_VALID=Request information is not valid |