스프링

 

스프링 부트 ( 2.7.0)    mybatis  사용

 

1.  공통기능 체크를 할 경우 HandlerInterceptor 와 annotation 사용 

 

1) RequestConfig  어노테이션 생성

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestConfig {

	boolean loginCheck() default false;
	
}

 

 

2) HandlerInterceptor

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import kr.net.macaronics.annotation.RequestConfig;
import kr.net.macaronics.configuration.http.BaseException;
import kr.net.macaronics.configuration.http.BaseResponseCode;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BaseHandlerInterceptor implements HandlerInterceptor {

  
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("\n\n\n*** [preHandle] URI : {} - 시작 " , request.getRequestURI());
		
        //preHandle 및 어노테이션 상용법 - 로그인 테스트
        if(handler instanceof HandlerMethod) {
        
        	HandlerMethod handlerMethod =(HandlerMethod) handler;
        	RequestConfig requestConfig=handlerMethod.getMethodAnnotation(RequestConfig.class);
        	
        	if(requestConfig!=null) {
        		//로그인 체크가 필수인 경우
        		if(requestConfig.loginCheck()) {
        			throw new BaseException(BaseResponseCode.LOGIN_REQUIRED.name());
        		}
        	}
        }
        
		return true;
    }
	
	
}

 

 

3) WebMvcConfig  에  빈 설정

	/**
	 *  BaseHandlerInterceptor 빈 설정
	 */
	@Bean
	public BaseHandlerInterceptor baseHandlerInterceptor() {
		return new BaseHandlerInterceptor();
	}
	

 

다국어 메시지 내용은 다음을 참조

RESTful API 개발 - ★ Swagger 설치 및 게시판 API 문서화 & API 공통 Response Class, Enum 사용하기 & ControllerAdvice 사용과 예외처리 다국어 활용

 

 

4)컨트롤에서 다음과 같이 사용.

 

@RequestConfig(loginCheck = true)

	/** 게시판 등록/수정처리 */
	@PutMapping("/save")
	@RequestConfig(loginCheck = true)
	@ApiOperation(value="등록/수정처리", notes="신규 게시물 저장 및 기존 게시물 업데이트가 가능합니다.")
	@ApiImplicitParams({
		@ApiImplicitParam(name="boardSeq", value="게시물번호", example = "1"),
		@ApiImplicitParam(name="boardType", value="게시판종류", example = "NOTICE"),
		@ApiImplicitParam(name="title", value="제목", example = "spring"),
		@ApiImplicitParam(name="contents", value="내용", example="spring 강좌"),
	})
	public BaseResponse<Integer> save(BoardInsertDTO boardInsertDTO)  throws Exception {
		boardService.save(boardInsertDTO);
		return new BaseResponse<Integer>(boardInsertDTO.getBoardSeq());
	}

 

체크 결과 =>

Response body

{
  "status": "ERROR",
  "code": "LOGIN_REQUIRED",
  "message": "요청하신 URL 은 로그인이 필수 입니다.",
  "pageMaker": null,
  "data": null
}

 


 

 

 

 

 

 

2. 공통 에러 설정

 

 

1)BaseResponseCode

import lombok.NoArgsConstructor;

@NoArgsConstructor
public enum BaseResponseCode {

	SUCCESS(200), // 성공
	ERROR(500), // 실패
	LOGIN_REQUIRED(403), 
	DATA_IS_NULL, 
	VALIDATE_REQUIRED;

	private int status;

	BaseResponseCode(int status) {
		this.status = status;
	}

	public int status() {
		return status;
	}

}

 

 

2) BaseResponse

import kr.net.macaronics.utils.pagination2.MysqlPageMaker;
import kr.net.macaronics.utils.pagination2.MysqlPageMakerResponse;
import lombok.Data;

@Data
public class BaseResponse<T> {

	private String status=BaseResponseCode.SUCCESS.name();
	private BaseResponseCode code;
	private String message;
	private MysqlPageMakerResponse pageMaker;
	private T data;
	
		
	public BaseResponse(T data) {		
		this.code=BaseResponseCode.SUCCESS;
		this.data=data;
	}
	
	public BaseResponse(String status, T data) {
		if(status.equals("error"))this.code=BaseResponseCode.ERROR;		
		else this.code=BaseResponseCode.SUCCESS;
		this.data=data;
	}
	
	
	public BaseResponse(BaseResponseCode code) {		
		this.code=code;	
	}


	public BaseResponse(String status, String code, String message) {		
		this.status=status;
		this.code =BaseResponseCode.valueOf(code);	
		this.message=message;				
	}

	
	
	public BaseResponse(String status, T data, String message) {
		if(status.equals("error"))this.code=BaseResponseCode.ERROR;		
		else this.code=BaseResponseCode.SUCCESS;
		this.data=data;
		this.message=message;
	}

	/** MysqlPageMaker 페이지 처리 메소드 */
	public BaseResponse(T data,  MysqlPageMaker mysqlPageMaker) {
		this.code=BaseResponseCode.SUCCESS;
		this.data=data;
		this.pageMaker=mysqlPageMaker.toResPageMaker(mysqlPageMaker);
	}
	
	
	
	
}

 

 

3)BaseException

import lombok.Getter;

@Getter
public class BaseException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public BaseException(String msg) {		
		super(msg);
	}
	

}

 

4) GlobalExceptionHandler

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import kr.net.macaronics.configuration.http.BaseException;
import kr.net.macaronics.configuration.http.BaseResponse;
import kr.net.macaronics.configuration.http.BaseResponseCode;
import lombok.extern.slf4j.Slf4j;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

	@Autowired
	MessageSource messageSource;

    @ExceptionHandler(BaseException.class)
    public BaseResponse<?> handleException(Exception ex){
        log.error("* GlobalExceptionHandler ===> {}, {}",ex.getMessage(), ex);
        String message=messageSource.getMessage(ex.getMessage(), null, LocaleContextHolder.getLocale());
        return new BaseResponse<>(BaseResponseCode.ERROR.name(), ex.getMessage(),  message);
    }
    
    
}

 

 

5) 기타 messages_ko.properties  다국어 메시지 설정

language = 한글
welcome = 안녕? {0}
testName= 제 이름은 {0} 입니다. 사는 곳은 {1} 입니다. 
LOGIN_REQUIRED =요청하신 URL 은 로그인이 필수 입니다.

login.info.error= 로그인 오류
user.password.hasLength= 비밀번호를 필수로 입력해주셔야 합니다.
user.password.isTrue= 비밀번호가 일치하지 않습니다.

 

6) 사용예

BaseHandlerInterceptor

throw new BaseException(BaseResponseCode.LOGIN_REQUIRED.name());

	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("\n\n\n*** [preHandle] URI : {} - 시작 " , request.getRequestURI());
		
        //preHandle 및 어노테이션 상용법 - 로그인 테스트
        if(handler instanceof HandlerMethod) {
        
        	HandlerMethod handlerMethod =(HandlerMethod) handler;
        	RequestConfig requestConfig=handlerMethod.getMethodAnnotation(RequestConfig.class);
        	
        	if(requestConfig!=null) {
        		//로그인 체크가 필수인 경우
        		if(requestConfig.loginCheck()) {
        			throw new BaseException(BaseResponseCode.LOGIN_REQUIRED.name());
        		}
        	}
        }
        
		return true;
    }

 

 

7) 출력

Response body

{
  "status": "ERROR",
  "code": "LOGIN_REQUIRED",
  "message": "요청하신 URL 은 로그인이 필수 입니다.",
  "pageMaker": null,
  "data": null
}

 

 

소스 )

https://github.com/braverokmc79/sprig_boot_2.7.0_mybatis_board_project/commit/a5be36f2278df4dc45d5d8a127e21cad5ef1d1fc

 

 

 

 

 

 

 

 

 

 

 

 

 

 

spring

 

about author

PHRASE

Level 60  라이트

잠 못 이루는 밤이 많아지면 음식을 조절하고 마음의 평정을 되찾고 주위를 차근차근 다스려 나가라. -도교

댓글 ( 4)

댓글 남기기

작성