본문 바로가기
Programming/Java

[Java / Spring ] 어노테이션(@, annotation)의 정의와 종류

by prinha 2020. 8. 12.
728x90
반응형

(계속 추가중 / 최종수정일:20200831)

어노테이션(@, annotation)이란?

Annotation은 Java5부터 새롭게 추가된 문법요소이다.

사전적으로는 "주석"이라는 의미를 가지고 있으며, 자바 코드에 @를 이용해 주석처럼 달아 특수한 의미를 부여해준다.

프로그램 코드의 일부가 아닌 프로그램에 관한 데이터를 제공하고, 코드에 정보를 추가하는 정형화된 방법이다.

어노테이션을 사용하면 코드가 깔끔해지고 재사용이 가능하다.

 

ps. 자바 리플렉션 : 다른 언어에는 존재하지않는 특별한 기능으로,

컴파일 시간이 아닌 실행 시간에 동적으로 특정 클래스의 정보를 객체를 통해 분석 및 추출해내는 프로그래밍 기법

 


@SpringBootApplication

@Configuration + @EnableAutoConfiguration + @ComponentScan

 

Srping Boot를 자동으로 실행시켜주는 어노테이션으로 Bean 등록은 두 단계로 진행된다.

1) @ComponentScan을 통해 Component들을 Bean으로 등록한다.

2) @EnableAutoConfiguration을 통해 미리 정의해둔 자바 설정 파일들을 Bean으로 등록한다.

 

 

@Configuration

스프링 IOC Container에게 해당 클래스가 Bean 구성 Class임을 알려주는 어노테이션이다.

-> @Bean을 해당 클래스의 메소드에 적용하면, @Autowired로 빈을 부를 수 있다.

( 설정에 관련된 정보 어노테이션 )

 

  

@Bean의 경우 개발자가 컨트롤이 불가능한 외부 라이브러리들을 Bean으로 등록하고 싶은 경우에 사용된다. 
(예를 들면 ObjectMapper의 경우 ObjectMapper Class에 @Component를 선언할수는 없으니 
ObjectMapper의 인스턴스를 생성하는 메소드를 만들고 해당 메소드에 @Bean을 선언하여 Bean으로 등록한다.)



반대로 개발자가 직접 컨트롤이 가능한 Class들의 경우엔 @Component를 사용한다.


그럼 개발자가 생성한 Class에 @Bean은 선언이 가능할까?
정답은 No 이다.
@Bean과 @Component는 각자 선언할 수 있는 타입이 정해져있어 해당 용도외에는 컴파일 에러를 발생시킨다.

 

@EnableAutoConfiguration

스프링 어플리케이션 컨텍스트를 만들 때 자동으로 설정하는 기능을 켠다.

classpath의 내용에 기반해서 자동 생성해 준다. 만약 tomcat-embed-core.jar가 존재하면 톰캣 서버가 setting된다.

 

@ComponentScan

@Component, @Service, @Repository, @Controller, @Configuration이 붙은 빈들을 찾아서

Context에 빈을 등록해 주는 어노테이션


@Component

개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션

 

@ComponentScan 선언에 의해 특정 패키지 안의 클래스들을 자동 스캔하여

@ComponentScan 어노테이션이 있는 클래스들에 대하여 빈 인스턴스를 생성한다.

@Component 어노테이션은 Controller, Service, DAO 세가지 이외의 클래스에만 사용 권장

 

-> 자동으로 등록되는 빈의 네임은 클래스의 첫문자가 소문자로 바뀌어 자동 적용된다.

(HomeController -> homeController)

 

@Component -> (구체화) -> @Controller, @Service, @Repository

 

@Controller

Spring MVC의 Controller로 사용되는 클래스 선언을 단순화 시켜주는 어노테이션

Controller 클래스의 리턴타입이 String이면 jsp파일명을 의미

@Service

비지니스 로직이 들어가는 Service로 사용되는 클래스임을 명시하는 어노테이션

 

@Repository

DB연동 작업을 하는 클래스인 DAO에 특화된 어노테이션으로,

해당 클래스에서 발생하는 DB 관련 예외를 spring의 DAOException으로 전환할 수 있는 장점이 있다.


@RequestMapping

클라이언트에게 요청받는 주소를 클래스와 연결시켜주는 어노테이션 (클래스 연결 중간점) / 디폴트 GET 방식

클래스와 메소드단 두 곳에서 모두 사용 가능

 

 

RequestMapping (Spring Framework 5.2.8.RELEASE API)

The parameters of the mapped request, narrowing the primary mapping. Same format for any environment: a sequence of "myParam=myValue" style expressions, with a request only mapped if each such parameter is found to have the given value. Expressions can be

docs.spring.io

 

@RequestMapping("/A/*")

/A/*(모든 주소 가능) 기본 주소 매핑 (접두사와 비슷한 의미)

 

@RequestMapping(value="/A", method=RequestMethod.POST)

http method방식으로 value url 주소 매핑

// 1)메소드 리턴타입이 void일 때
// 주소 : /nowrite
// 리턴타입(이동 페이지) : nowrite.jsp (value가 jsp파일명)
@RequestMapping(value="nowrite", method=RequestMethod.GET)
public void write() {

}


// 2)메소드 리턴타입이 String일 때
// 주소 : /noticeEdit
// 리턴타입(이동 페이지) : noEditForm.jsp (리턴타입이 jsp파일명)
@RequestMapping(value="noticeEdit", method=RequestMethod.GET)
public String noticeEdit(int idx) throws Exception {
		
	return "/noEditForm";
}


// 3) 클래스에서 사용시
// 기본 주소에 /jpa를 무조건 포함
@RestController
@RequestMapping("/jpa")
public class UserJpaController{...}

 

Spring 4.3부터 Spring MVC Controller Method를 위한 어노테이션이 추가되었는데

각각의 어노테이션들은 HttpMethods에 매칭되며, method단에서 사용 가능하다.

  • @PostMapping
  • @GetMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
// 변경전
@RequestMapping(value="/getList", method={RequestMethod.POST})

// 변경후
@PostMapping("/getList")

의존성 자동 주입 어노테이션

@Resource,  @Autowired,  @Inject

모두 의존 관계를 자동으로 연결하여 빈을 주입해주는 기능을 가진 어노테이션

  @Resource @Autowired  @Inject
 범용 Java에서 지원하는 어노테이션 Spring Framework에서 지원 Java에서 지원하는 어노테이션
사용하는 위치 필드, 파라미터가 한개인 setter 메소드
(기본 생성자 정의 필수)
필드, 생성자, setter 메소드
(기본 생성자 정의 필수)
필드, 생성자, setter 메소드
(기본 생성자 정의 필수)
연결 또는 검색 방식
(우선 순위)
이름(id)이 일치하는 객체 자동 주입 (이름 -> 타입) 타입이 일치하는 객체 자동 주입 (타입 -> 이름) 타입이 일치하는 객체 자동 주입 (타입 -> 이름)
특이사항 
 스프링에서만 사용 가능
강제 연결 하기  @Resource(name="id")
id=> servlet-context.xml의 bean id
@Autowired 
@Qualifier("value")
@Inject
@Named("id")

@RestController (Spring RestFul Controller)

(@Controller + @ResponseBody) 결합 형태의 어노테이션으로,

주 용도는 해당 클래스가 ajax 요청을 받아 Json/Xml 형태로 객체 데이터를 반환하는 것이다.

 

★기존 MVC @Controller와의 차이점은 HTTP Response Body가 생성되는 방식의 차이이다.

@RestController : (주용도 데이터 리턴)클래스의 리턴타입이 String이면 문자열 데이터 의미(jsp파일 사용 X)

@Controller : (주용도 view 리턴)클래스의 리턴타입이 String이면 리턴값이 jsp파일명을 의미

-> 물론 @Controller의 경우 메소드에 @ResponseBody를 사용하여 객체를 리턴할 수도 있다.

@Controller의 실행 흐름
Client -> Request -> Dispatcher Servlet -> Handler Mapping -> Controller -> View -> Dispatcher Servlet -> Response -> Client 


@ResponseBody의 실행 흐름
Client -> Request -> Dispatcher Servlet -> Handler Mapping -> Controller (ResponseBody) -> Response -> Client 


@RestController의 실행 흐름
Client -> HTTP Request -> Dispatcher Servlet -> Handler Mapping -> RestController (자동 ResponseBody 추가)-> HTTP Response -> Client

json 문법 구조 포맷으로 전송되어 온 데이터를

내보낼 때에는 ResponseBody / 가져올 때에는 @RequestBody

-> jackson 라이브러리 필요

@ResponseBody

자바 객체를 HTTP 요청의 body 내용으로 변환/매핑하는 어노테이션

@RequestBody

HTTP 요청의 body 내용을 전달받아 자바 객체로 변환/매핑하는 어노테이션

 

 

@Controller 
public class MainController {
	// home.jsp 
	@RequestMapping(value = "/", method = RequestMethod.GET) 
	public String home() { 
		return "home"; 
	} 

	@ResponseBody 
	@RequestMapping(value = "/test", method = RequestMethod.POST) 
	public void init(@RequestBody UserVO userVO) {
		userVO.getName(); // "kim" 
		userVO.getAge(); // 30 
	} 
}

HttpEntity 클래스 : Http 프로토콜을 이용하는 통신의 header와 body 관련 정보를 저장

요청하거나 요청 받은 정보에 대한 HTTP 상태 코드를 리턴하거나 리턴받아서 정상 처리가 되었는지 에러가 났는지 알 수 있다.

즉, 통신 메시지 관련 header와 body의 값들을 하나의 객체로 저장하는 것이 HttpEntity 클래스 객체이다.

이를 상속받은 클래스로 RequestEntity와 ResponseEntity가 존재한다. 

header값을 변경시켜야 할 경우에는 @ResponseBody의 경우 파라미터로 Response 객체를 받아 해당 객체에서 header를 변경시켜야하고, ResponseEntity에서는 해당 클래스의 객체를 생성한 뒤 객체에서 header 값을 변경시켜야 한다.

 

RequestEntity  ResponseEntity

@RequestMapping(value="/{rno}", method = {RequestMethod.PUT,RequestMethod.PATCH})
public ResponseEntity<String> replyUpdate(@PathVariable("rno") int rno, @RequestBody ReplyVO vo){
	
    // (HTTP 상태 코드 + 데이터)를 클라이언트에게 리턴
	ResponseEntity<String> entity = null;

	try {
		// rno 세팅 해주기
		vo.setRno(rno); 
		service.replyUpdate(vo);
		entity= new ResponseEntity<String>("SUCCESS",HttpStatus.OK);
		
	}catch(Exception e) {
		e.printStackTrace();
		entity= new ResponseEntity<String>(e.getMessage(),HttpStatus.BAD_REQUEST);
	}
	
	return entity;
}

 

@ResponseBody와 ResponseEntity의 차이

두 가지는 똑같은 결과 값을 가지고 오지만 ResponseEntity를 사용하는 용도는

HTTP response header의 융통성 있는 추가가 가능하다.

 

따라서 굳이 HTTP 설정이 필요하지않다면 , ResponseBody의 사용이 더 간결하다.


@PathVariable

URL 경로 주소에 사용하는 값을 매개 변수로 사용 가능하게 해주는 어노테이션(RESTful)

 

@RequestMapping의 URL 정의 부분과 Method 내의 Parameter 부분에 정의를 하여 사용이 가능하다.

@RequestMapping 어노테이션 값으로 {템플릿변수} 를 사용한다.

@PathVariable 어노테이션을 이용해서 {템플릿 변수} 와 동일한 이름을 갖는 파라미터를 추가한다.

RequestMapping 어노테이션에 변수를 포함하고 있으면서,

이들 변수는 @PathVariable 어노테이션이 적용된 동일한 이름을 갖는 파라미터에 매핑됩니다.

@RequestMapping(value="/{rno}",method=RequestMethod.DELETE)
public ResponseEntity<String> replyDel(@PathVariable("rno") int rno){
    
	ResponseEntity<String> entity = null;
	
	try {
		service.replyDel(rno);
		entity=new ResponseEntity<String>("SUCCESS",HttpStatus.OK);
	}catch(Exception e) {
		e.printStackTrace();
		entity=new ResponseEntity<String>(e.getMessage(),HttpStatus.BAD_REQUEST);
	}
	
	return entity;
}

 

rest방식에서는 value="" 주소를 경로(path) 형태로 만들어 주기 (쿼리 스트링 X)

-> 주소이면서 데이터를 포함하고 있는 의미

 

RequestParam을 사용했을 때 주소

http://localhost:8080/?aaa=bbb&ccc=ddd

 

PathVariable을 사용했을 때 주소

http://localhost:8080/bbb/ddd


Spring에서 예외를 처리하는 어노테이션 3가지

1) @ExceptionHandler

기존 Controller에 @ExceptionHandler 어노테이션을 사용하은 메소드를  추가하여 예외처리를 하는 방식

@RequestMapping 대신 @ExceptionHandler 어노테이션을 사용하기만 하면 된다.

각 컨트롤러에 예외처리를 위한 메소드를 추가해주는 방식은 컨트롤러의 수가 많아지면 그만큼 작업해야 할 양이 많아진다.

사이트 전체에 공통으로 적용해야할 컨트롤러에는 @ControllerAdvice를 사용한 예외 처리 방법이 효율적이다.

 

2) @ResponseStatus

HTTP Status Code 제어를 위한 Exception handling 특정한 예외 지정

 

ex. 존재하지않는 id 값을 검색하여 null 값을 return 받았을 때

예외처리를 시작하기 전 에러화면을 보면 상태코드 값이 '500'이다.

500 Internal Server Error 예외 발생

 

이 값은 서버에서 문제가 생겼을 때 통상적으로 반환되는 상태코드 값인데, 

문제에 대한 정확한 원인을 파악하기가 힘들다는 단점이 있다.

따라서, 이 상태코드를 의미가 있는 코드로 변환하여 돌려주는 것이 문제 해결에 도움이 된다.

이럴 때 사용하는 것이 @ResponseStatus 어노테이션이다.

 

// UserDAOService

public User findOne(int id){
    for(User user : users){
        if(user.getId()== id){
            return user;
        }
    }
    return null;
}
// UserController

@GetMapping("/users/{id}")
public User retrieveUser(@PathVariable  int id){
    User user = service.findOne(id);

    if(user==null){
        throw new UserNotFoundException(String.format("ID[%s] not found", id));
    }
    return user;
}
// UserNotFoundException 예외 클래스 생성

package com.example.restfulwebservice.user;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

// HTTP Status Code
// 2XX -> OK
// 4XX -> Client 오류
// 5XX -> Server 오류
// 데이터가 존재하지않는 오류기때문에
// '5XX 오류메시지'가 아니라 'NotFound' 오류메시지지 전달해주기
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

404 Not Found Status Code 전달 받음

 

3) @ControllerAdvice

Spring AOP를 이용한 Exception handling으로 '예외처리 전용 컨트롤러'생성하여 예외 처리를 하는 어노테이션이다.

모든 컨트롤러가 실행될 때 @ControllerAdvice 어노테이션을 가지고 있는 빈이 자동 실행된다.

exception 패키지-클래스 생성

 

// ExceptionResponse

package com.example.restfulwebservice.exception;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;

// 예외처리를 하기위해 사용되는 자바 객체
// 모든 Controller에서 사용할 수 있는 일반화된 예외 클래스
// AOP 기능 사용
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExceptionResponse {
    private Date timestamp; // 예외가 발생한 시간 정보
    private String message; // 예외가 발생한 메시지
    private String details; // 예외 상세 정보
}

 

ResponseEntityExceptionHandler class를 상속받는 예외 핸들링 클래스 생성

package com.example.restfulwebservice.exception;

import com.example.restfulwebservice.user.UserNotFoundException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.Date;

// ResponseEntityExceptionHandler를 상속받는 클래스
// 사용하는 시스템에서 에러가 발생하게되면,
// 에러를 핸들링하기 위해 스프링 부트에서 제공되는 클래스
@RestController
@ControllerAdvice
// 모든 컨트롤러가 실행이 될때 @ControllerAdvice 어노테이션을 가지고 있는 빈이 실행되게 되어있는데
// 만약 에러가 발생하면 예외 핸들러 클래스가 실행됨
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    // 모든 예외처리를 처리해주는 메소드
    @ExceptionHandler(Exception.class)
    public final ResponseEntity<Object> handleAllException(Exception ex, WebRequest request){

        // handleAllException(Exception ex, WebRequest request)
        // Exception ex : 에러객체
        // WebRequest : 어디서 발생했는지에 대한 정보

        ExceptionResponse exceptionResponse = new ExceptionResponse( new Date(), ex.getMessage(), request.getDescription(false));

        // 서버에서 가장 일반화되어있는 오류 : 500번 / HttpStatus.INTERNAL_SERVER_ERROR
        return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    // 사용자가 존재하지않았을 때 사용하는 UserNotFound Exception
    @ExceptionHandler(UserNotFoundException.class)
    public final ResponseEntity<Object> handleUserNotFoundException(Exception ex, WebRequest request){

        // handleAllException(Exception ex, WebRequest request)
        // Exception ex : 에러객체
        // WebRequest : 어디서 발생했는지에 대한 정보

        ExceptionResponse exceptionResponse = new ExceptionResponse( new Date(), ex.getMessage(), request.getDescription(false));

        // NOT_FOUND
        return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND);
    }

    // 사용자가 입력한 값에 문제가 생겼을 때 사용하는 예외 메소드 재정의
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) {

       // ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(),
                //ex.getMessage(),ex.getBindingResult().toString());
        ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(),
             "Validation Failed",ex.getBindingResult().toString());

        return new ResponseEntity(exceptionResponse,HttpStatus.BAD_REQUEST);
    }
}

  

ex. 존재하지않는 사용자를 검색했을 때 발생한 404 UserNotFound Exception

 


@Valid

https://docs.jboss.org/hibernate/beanvalidation/spec/2.0/api/

RestController를 이용하여 @RequestBody 객체를 사용자로부터 가져올 때, 들어오는 값들을 유효성 검사 

@Valid를 이용하면, service 단이 아닌 객체 안에서, 들어오는 값에 대해 검증을 할 수 있다.

 

 

// User

import lombok.AllArgsConstructor;
import lombok.Data;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import java.util.Date;

@Data
@AllArgsConstructor
public class User {
    private Integer id;

    @Size(min=2, message = "Name은 2글자 이상 입력해주세요.")
    private String name;

    // 과거 데이터 제약 조건
    @Past
    private Date joinDate;
}
// UserController

// @Valid 어노테이션 추가
// 새로운 사용자를 등록하는 method 구현
 @PostMapping("/users")
 public ResponseEntity<User> createUser(@Valid @RequestBody User user){
     User savedUser = service.save(user);

     URI location = ServletUriComponentsBuilder.fromCurrentRequest()
             .path("/{id}")
             .buildAndExpand(savedUser.getId())
             .toUri();

     return ResponseEntity.created(location).build();
 }
// CustomizedResponseEntityExceptionHandler
 
 // 사용자가 입력한 값에 문제가 생겼을 때 사용하는 예외 메소드 재정의
 @Override
 protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                   HttpHeaders headers,
                   HttpStatus status,
                   WebRequest request) {

        ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(),
                 ex.getMessage(),ex.getBindingResult().toString());

        return new ResponseEntity(exceptionResponse,HttpStatus.BAD_REQUEST);
    }

 

message와 details를 간단하게

 

 

1) 문자열 유무 검증 (@NotBlank, @NotEmpty, @NotNull)

@NotBlank 
  - null 이 아닌 값이다.
  - 공백이 아닌 문자를 하나 이상 포함한다.

@NotEmpty
  - Type : CharSequence (length of character) Collection (collection size) Map (map size Array (array length)
  - null 이거나 empty(빈 문자열)가 아니어야 한다.

@NotNull
  - Type : 어떤 타입이든 수용한다.
  - null 이 아닌 값이다.

@Null
  - Type :어떤 타입이든 수용한다.
  - null 값이다.

 

  • @NotNull : 반드시 값이 있어야 한다.
  • @NotEmpty : 반드시 값이 존재하고 길이 혹은 크기가 0보다 커야한다.
  • @NotBrank : 반드시 값이 존재하고 공백 문자를 제외한 길이가 0보다 커야 한다.
  null "" " "
@NotNull Invalid Valid Valid
@NotEmpty Invalid Invalid Valid
@NotBlank Invalid Invalid Invalid

 

2) 최대, 최소에 대한 검증

@DecimalMax : 지정된 최대 값보다 작거나 같아야 한다.
      Require : String value  => max 값을 지정한다.
@DecimalMin : 지정된 최대 값보다 크거나 같아야 한다.
      Require : String value  => min 값을 지정한다.
@Min : 지정된 최대 값보다 작거나 같아야 한다.
      Require : int value  => max 값을 지정한다.
@Max : 지정된 최대 값보다 크거나 같아야 한다.
      Require : int value  => min 값을 지정한다.

 

-> String을 사용하느냐 Integer를 사용하느냐에 따라 범위 값이 현저히 달라진다.

 

3) 최대, 최소에 대한 검증

@Positive : 양수인 값이다.
@PositiveOrZero : 0이거나 양수인 값이다.
@Negative : 음수인 값이다.
@NegativeOrZero : 0이거나 음수인 값이다.

 

4) 시간 값에 대한 검증

@Future : Now 보다 미래의 날짜, 시간이어야 한다.
@FutureOrPresent : Now 거나 미래의 날짜, 시간이어야 한다.
@Past : Now 보다 과거 의의 날짜, 시간이어야 한다.
@PastOrPresent : Now 거나 과거의 날짜, 시간이어야 한다.

 

5) 이메일 검증

@Email : 올바른 형식의 이메일 주소여야 한다. (@가 들어가야한다.)

 

6) 자릿수 범위 검증

@Digits허용된 범위 내의 숫자이다.
      Require : int integer  => 이 숫자에 허용되는 최대 정수 자릿수
      Require : int fraction  => 이 숫자에 허용되는 최대 소수 자릿수

@NoArgsConstructor
@Getter
@ToString
@Builder
@AllArgsConstructor
public class DigitsDto {
    @Digits(integer = 5, fraction = 5)
    private Integer digits;
}

 

7) boolean 값에 대한 검증

@AssertTrue : 값이 항상 True 여야 한다.
@AssertFalse : 값이 항상 False 여야 한다.

 

8) 크기(길이) 검증

@Size이 크기가 지정된 경계(포함) 사이에 있어야 한다.
      Require : int max  => element의 크기가 작거나 같다.
      Require : int min  => element의 크기가 크거나 같다.

@Min과 @Max는 String (숫자를 나타냄), int, short, byte 등의
숫자 필드와 해당 기본 래퍼 일 수있는 유효성 검사에 사용됩니다.

@Size는 필드의 길이 제한 조건을 확인하는 데 사용됩니다.
@Min과 @Max는 프리미티브와 래퍼를 지원하는 반면 @Size는 String, Collection, Map 및 배열을 지원합니다.

 

9) 정규식 검증

@Pattern :지정한 정규식과 대응되는 문자열 이어야 한다. Java의 Pattern 패키지의 컨벤션을 따른다.
      Require : String regexp  =>정규식 문자열을 지정한다.

@NoArgsConstructor
@Getter
@ToString
public class PatternDto {
    //yyyy-mm-dd 형태를 가지는 패턴 조사
    @Pattern(regexp = "^(19|20)\\d{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[0-1])$")
    private String pattern;
}

데이터 제어를 위한 Filtering 어노테이션 -> 보안상의 문제 해결

@JsonIgnore

필드 하나 하나에 개별적으로 필터 어노테이션 적용

// User

package com.example.restfulwebservice.user;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;

@Data
@AllArgsConstructor
public class User {

    private Integer id;
    private String name;
    private Date joinDate;

    // 중요한 데이터
    @JsonIgnore
    private String password;
    @JsonIgnore
    private String ssn;
}

 

@JsonIgnoreProperties

클래스 블록에 필터 어노테이션 적용

// User

package com.example.restfulwebservice.user;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;

@Data
@AllArgsConstructor
@JsonIgnoreProperties(value={"password","ssn"}) //클래스 블록에 추가
public class User {

    private Integer id;
    private String name;
    private Date joinDate;

    // 중요한 데이터
    private String password;
    private String ssn;
}

 

@JsonFilter() 

어드민 페이지에서 지정된 필드만 조회할 때 사용하는 필터 (Controller, Service 클래스에서 사용)

// User

package com.example.restfulwebservice.user;
import com.fasterxml.jackson.annotation.JsonFilter;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;

@Data
@AllArgsConstructor

@JsonFilter("UserInfo") 
// Controller, Service 클래스에서 사용
// Filter ID를 문자열로 지정하며, 이 어노테이션 사용시에는 무조건
// FilterProvider와 해당 ID를 처리하는 필터를 제공해야함
public class User {

    private Integer id;
    private String name;
    private Date joinDate;
    private String password;
    private String ssn;
}
// AdminUserController
// 개별 사용자 조회

@GetMapping("admin/users/{id}")
public MappingJacksonValue retrieveUser(@PathVariable  int id){
   
   User user = service.findOne(id);

   // SimpleBeanPropertyFilter : 지정된 필드들만 JSON 변환하고, 알 수 없는 필드는 무시
   SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
           .filterOutAllExcept("id","name","joinDate","ssn");

   FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo",filter);

   MappingJacksonValue mapping = new MappingJacksonValue(user);
   mapping.setFilters(filters);

   return mapping;
}

 

admin 페이지에서 작성한 filterOutAllExcept("id","name","joinDate","ssn"); 데이터만 조회 가능

 

 

MappingJacksonValue

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJacksonValue.htm


@EnableSwagger2

개발자 도움말 페이지를 생성해주는 어노테이션 

 

 

[Spring Boot] RESTful Service 강의 정리 (7) - Configuring Auto Generation of Swagger Documentation / 개발자 도움말 페

[Spring Boot] RESTful Service 강의 정리 (6) - Implementing HATEOAS / level3단계의 REST API 구현 [Spring Boot] RESTful Service 강의 정리 (5) - REST API Version 관리(URI, Request Parameter, Header, Mi..

prinha.tistory.com

 

 


출처 및 참고

https://toma0912.tistory.com/9

https://m.blog.naver.com/kyy627/221744688311

https://jeong-pro.tistory.com/151

https://atoz-develop.tistory.com/entry/Spring-DI-%EC%95%A0%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-%EC%A0%95%EB%A6%AC-Autowired-Resource-Inject

https://itjava.tistory.com/54

https://codevang.tistory.com/256

https://lkg3796.tistory.com/58

https://lee-mandu.tistory.com/242

https://sarc.io/index.php/development/1145-pathvariable

https://jyami.tistory.com/55

https://jojoldu.tistory.com/27

 

 

 

728x90
반응형