기본 웹 어플리케이션은 응답 결과를 브라우저가 사용하는 코드인 HTML, CSS, JavaScript로 생성하여 전달한다. 이 데이터들은 브라우저가 화면을 구성하고 꾸미며 기능을 수행하기 위한 코드들이다. 

Restful API 서버는 응답 결과를 데이터만으로 구성하여 클라이언트로 전달하는 서버를 의미한다. 서버가 가진 데이터를 JSON문서양식에 맞춰서 응답결과로 클라이언트에게 보낸다.

Restful API 서버는 웹에서 Ajax통신이나 안드로이드 모바일 서비드를 할 때 등 다양한 플랫폼으로 데이터를 전달할 때 사용할 수 있다. 최근들어서 React, Angluar, Vue.js와 같은 Script기반의 웹 어플리케이션을 만들 때 많이 사용하고 있는 방법이다..!

 

 

 

@RestController

Spring MVC에서 Controller를 구성할 때 @Controller를 사용하면 return하는 값은 사용할 jsp에 대한 정보를 가진다.

그런데 @RestController를 통해서 return을 하게 되면 리턴값 자체를 브라우저로 전달하는 응답결과로 생성하여 보내게 된다. 예를들어 return "result"; 하면 result라는 문자열이 데이터로서 전달 된다고 할 수 있겠다.

 

 

Jackson 라이브러리

Jackson 라이브러리를 사용하여 객체나 리스트를 반환하게 되면 반환하는 대상을 JSON형식으로 바꾸어서 리턴해준다.

pom.xml에 dependency를 추가하여 라이브러리를 사용해보자.

 

 

Jackson Databind라고 검색하여 Maven부분을 추가해주도록 하자.

 

 

 

버전관리를 위해서 version은 따로 정의했다.

 

 

 

DataBean이라는 빈클래스를 만들었다. 어떠한 형태이든 JSON으로 변환됨을 확인하기 위해서 String, int, double, boolean형의 프로퍼티 총 4개를 만들었다. 간단하게 값을 넣을 수 있도록 생성자를 통해서 주입이 가능하도록 만들어 보았다.

 

 

 

Controller 부분이다.

@Controller가 아닌 @RestController를 써줌으로써 이 컨트롤러의 return값은 그 값 자체를 응답결과로 보낼 수 있다.

 

ResponseEntity<T> 형태의 메소드를 정의해주었다.

이 메소드에서는 Databean 빈 클래스 객체 3개를 ArrayList<Databea>형의 리스트에 넣어주었다. 리스트에는 객체 3개가 담겼을 것이다.

 

ResponseEntity<T>의 제네릭에 ArrayList<Databean>을 넣어주면 리스트안에 들어있는 객체의 구조를 파악해서 JSON문서로 만들어주게 된다. JSON객체를 첫번째 매개변수에, 응답결과를 두번째 매개변수에 넣어주었다.

 

 

 

실행결과

 

 

이렇게 JSON형식의 데이터가 반환이 되는 것을 볼 수 있었다.

RestfulAPI는 클라이언트로 전달할 데이터의 총량을 줄이기 위해서 들여쓰기나 칸을 내려서 쓰지 않는다.

한눈에 JSON형식을 보려면 Chrom 웹 스토어에서 JSON Formatter를 설치하면 된다.

 

 

 

 

JSON Formatter를 설치한 후 실행해보면

 

 

이렇게 한눈에 볼 수 있는 JSON파일 양식을 얻을 수 있다.

리스트이기 때문에 1, 23줄을 대괄호( [] )로 묶여 있고, 리스트안에는 객체가 들어있기 때문에 3, 8줄과 같이 중괄호( {} )로 묶여 있는 것을 볼 수 있다.

'JAVA > Spring MVC' 카테고리의 다른 글

예외처리  (0) 2020.05.03
Interceptor  (0) 2020.05.03
JSR-303, JSR-380 어노테이션  (0) 2020.05.01
에러메세지 커스터마이징  (2) 2020.04.30
Spring MVC 유효성검사  (0) 2020.04.30

프로그램 실행 중 오류가 발생하게 되면 프로그램의 실행이 중단되게 된다. JAVA에서는 이를 방지하기 위해서 오류처리라는 개념을 두었다. 보통 웹 어플리케이션에서 오류가 발생하면 웹 브라우저에 오류메세지가 나타나게 되는데 이는 개발자 입장에서는 오류를 점검하고 디버깅을 하기 위해 사용될 수 있겠지만, 실제 사용하는 클라이언트가 보기에는 매우 부적절한 페이지이다. 그래서 보통은 오류가 발생하면 보여줄 jsp를 구성하고 오류가 발생하면 이 jsp로 응답 결과를 생성하여 브라우저로 전달하게 된다.

 

SpringMVC에서는 어떻게 오류페이지에 대한 처리를 할 수 있는지 알아보자.

 

 

 

@ExceptionHandler

Controller에서 @ExceptionHandelr를 통해 메소드를 정의해주면 오류가 발생할 때 이 메소드를 자동으로 호출해주게 된다. 이 메소드가 반환하는 jsp정보를 통해 응답 결과 화면을 만들고 이 응답 결과를 브라우저로 전달하게 된다. 

이때 사용되는 jsp를 오류 페이지용으로 만들어주면 되겠다.

 

 

 

컨트롤러이다. test1이라는 주소값 요청이 들어오면 test1이라는 메소드가 자동으로 호출하게 된다. test1이라는 메소드는 Model객체를 사용하여 array1이라는 정수형 배열의 6번째 인덱스를 "array1"이라는 이름으로 Request영역에 넘겨준다. 그런데, array1배열에는 6번째 인덱스가 존재하지 않는다. ArrayIndexOutOfBoundsException이 발생할 것이다. 

 

ArrayIndexOutOfBoundsException 예외가 발생하면 개발자가 지정한 오류페이지로 접근할 수 있도록 해보자.

@ExceptionHandler의 속성에 위와 같이 처리할 예외와 관련된 클래스를 넣어주면 이 예외가 발생할 때 등록된 메소드가 호출이 되도록 만들 수 있다. 

 

error1.jsp라는 오류페이지를 만들어주면 되겠다.

 

 

 

Global Exception Handler

@ExceptionHandler는 Controller마다 만들어 주어야 한다. 만약 Controller마다 발생 가능한 예외들이 있다면 한번만 정의해서 사용하는것이 효율적일 것이다. Global Exception Handler를 구현하면 Controller에 정의한 ExceptionHandler중에 해당 오류에 대한 것이 없다면 Global Exeption Handler로 이동하여 예외에 관련된 처리를 해주게 된다.

 

 

 

com.study.spring.exception 패키지를 새로 만들어서 GlobalExceptionHandler.java를 만들었다.

@ControllerAdvice를 클래스에 붙여줌으로써 해당 클래스를 Global Exception Handler로서 사용하겠다고 선언한다.

 

이 클래스는 RuntimeException을 반드시 상속받아야 한다.

모든 컨트롤러에서 공통적으로 발생할 수 있는 예외에 대한 정보를 이 클래스에 모두 선언해주면 된다.

NullPointException 예외를 등록해주었다.

 

이제 어떤 컨트롤러에서든 NullPointException이 발생하게 된다면 error2.jsp를 실행할 것이다.

 

 

 

'JAVA > Spring MVC' 카테고리의 다른 글

RestController  (0) 2020.05.04
Interceptor  (0) 2020.05.03
JSR-303, JSR-380 어노테이션  (0) 2020.05.01
에러메세지 커스터마이징  (2) 2020.04.30
Spring MVC 유효성검사  (0) 2020.04.30

우리는 Spring Core에서 AOP에 대한 개념을 학습했었다.

 

2020/04/17 - [JAVA/Spring] - AOP

 

AOP

AOP이란? Aspect Oriented Programming : 관점 지향 프로그래밍 하나의 프로그램을 관점(관심사)라는 논리적인 단위로 분리하여 관리하는 개념이다. 여기에서 관심사란 메소드 호출이나 특정주소를 요청하는 등의..

programmingrecoding.tistory.com

Interceptor는 이러한 AOP의 개념을 적용한 Spring MVC의 요소라고 할 수 있다.

Interceptor는 요청 주소에 대해 관심을 갖고 요청이 발생하게 되면 요청 주소를 확인하여 Controller의 메소드를 호출하기 전이나 후에 다른 메소드를 호출 할 수 있도록 가로채가는 개념이다.

요청 발생 시 호출되는 메소드의 코드가 중복되는 부분이 있을 때 Interceptor를 통해 처리하게 된다.

 

이는 로그인 여부 확인, 등급별 서비스 사용 권한 확인 등의 작을 처리할 때 많이 사용된다.

 

 

Interceptor는 HandlerInterceptor인터페이스를 구현하거나 HandlerInterceptorAdapter를 상속받은 클래스를 만들고 다음 메소드를 구현한다.

HandlerInterceptor에는 디폴트 메소드로 메소드가 정의되어 있다. Spring 예전버전에서는 메소드가 모두 추상메소드여서 전부 구현클래스에서 오버라이딩하여 구현을 했어야 했으나, 디폴트 메소드로 되어있기때문에 필요한 메소드만 오버라이딩해서 사용하면 되겠다. 

 

HandlerInterface의 구조

 

대표적인 메소드 3개를 알아보자. 

 

preHandle 

Controller의 메소드가 호출되기 전에 호출이 된다. 이 메소드가 false를 반환하면 코드의 흐름이 중단된다. PreHandle 이후에 postHandle이나 afterComletion이 있어도 코드의 흐름은 중단된다. 그렇기 때문에 페이지도 다음으로 넘어가지지 않는다.

 

postHandle

Controller의 메소드가 수행이 완료된 후, View처리를 수행하기 전에 호출된다. 

 

afterCompletion

View처리까지 완료되고 응답결과가 브라우저로 전달되기 전에 호출된다.

 

 

 

 

위와 같이 HandlerInterface 인터페이스의 구현 클래스를 정의한 후에는 Interceptor를 등록해주어야 한다.

등록은 Java로 설정되어 있는 프로젝트와 Xml로 설정되어 있는 프로젝트의 셋팅방법이 다르다. 

 

 

ServletAppContext.java

 

Spring 설정파일에 다음과 같이 addInterceptor라는 메소드를 오버라이딩 해줌으로서 Interceptor를 등록할 수 있다. 이 메소드는 WebMvcConfigurer 인터페이스의 default 메소드이기 때문에 선택적으로 오버라이딩하여 사용할 수 있다.

 

아까 정의하였던 HandlerInterceptor구현클래스의 객체를 만들고 InterceptorRegistration형의 변수에 addInterceptor메소드를 활용하여 객체를 매개변수로서 삽입해준다. 그 후 그 변수에 addPathPetterns메소드를 사용하여 요청 경로를 넣어준다. 여기에 등록된 요청주소와 일치하는 주소가 요청되면 Interceptor로 등록된 구현 클래스의 메소드에 따라서 preHandle이나 postHadle이나 afterCompletion이 위치에 맞게 호출되게 된다. 

Controller로 바로 가는게 아니라 Interceptor에 있는 메소드를 실행하는 것이다.

 

 

 

Servlet-Context.xml

 

xml파일에서 interceptor를 등록하는 방법이다.

HandlerInterceptor를 구현한 클래스를 빈으로 등록한 후, 그 빈을 <interceptor>태그안의 <beans:ref>태그를 이용해서 주입해준다. interceptor가 여러개라면 <interceptors>태그안에 여러개의 <interceptor>를 등록해주면 되겠다.

 

 

 

 

 

위의 예제를 실행해보면, 

 

실행결과

 

이렇게 정상적으로 메소드의 순서를 가로채서 호출이 완료된다.

Interceptor는 코드의 흐름을 잘 알 필요가 있다.. 헷갈린다. 

만약 Interceptor가 2개이면 perHanlde은 위에서 아래 방향으로 코드가 실행되지만 PostHandel과 afterCompletion은 아래에서 위로 실행된다. 

 

 

 

TestInterceptor1과 똑같이 preHadle, postHandle, afterCompletion이 있는 TestInterceptor2를 만들어서 interceptor2로 등록을 해준 후 실행을 해보았다.

 

 

 

실행결과

 

실행결과를 보면 preHandle은 위에서 아래로 순서대로 TestInterceptor1, TestInterceptor2가 실행되었지만 postHandle과 afterCompletion은 아래에서 위로 코드가 진행되어 TestInterceptor2가 TestInterceptor1보다 먼저 실행되는 결과를 볼 수 있었다.

 

 

 

자바이든 xml이든 interceptor가 요청되야 할 Path를 지정해주었었다. 매번 요청주소값을 정확히 할 수 없을 뿐더러 하위주소가 여래개 있을 때에는 패턴을 이용해서 등록해주는 것이 좋다.

 

 

Pattern

* : 이름 하나를 의미하며 글자수, 글자등 제한x
   -> /a/* 하면 a까진 똑같고 *에는 아무거나

? : 글자하나를 의미
** : 하위 이름까지 포함하여 글자수, 글자 제한x
   -> /k, /a/b, /b/B  : /** 저거 다 포함 
   -> /** 하면 뒤에 몇덩어리가 나와도 상관 x, 그냥 / 에도 반응한다.

excludePathPatterns("/*"); 하면 덩어리 한개만있는거는 관심사에서 제외하겠다는 의미이다.

'JAVA > Spring MVC' 카테고리의 다른 글

RestController  (0) 2020.05.04
예외처리  (0) 2020.05.03
JSR-303, JSR-380 어노테이션  (0) 2020.05.01
에러메세지 커스터마이징  (2) 2020.04.30
Spring MVC 유효성검사  (0) 2020.04.30

Bean Validation

 

Bean Validation은 JavaBean 유효성 검증을 위한 메타데이터 모델과 API에 대한 정의이며 여기서 언급하고 있는 JavaBean은 직렬화 가능하고 매개변수가 없는 생성자를 가지며, Getter 와 Setter Method를 사용하여 프로퍼티에 접근이 가능한 객체이다. 

Bean Validation 1.0 은 JSR-303이고 Bean Validation 2.0 은 JSR-380이다.

JSR-303과 JSR-380에는 어떠한 어노테이션을 이용하여 빈의 유효성을 정의할 수 있는지 알아보도록 하자.

 

https://beanvalidation.org/1.0/spec/ - JSR-303 명세서

https://beanvalidation.org/2.0-jsr380/spec/ - JSR-380 명세서

 

 

 

 

JSR-303

 

 

많이 사용되는 JSR-303 어노테이션들이다.

 

@Size(min=?, max=?)

min와 max의 값을 포함한 문자열의 최소길이와과 최대길이를 지정할 수 있다. 예를 들어, min이 2, max가 10이라면 data1에 들어갈 수 있는 문자열의 길이는 2~10글자수이다.

 

 

@Max(?), @Min(?)

정수의 최대값과 최소값을 지정할 수 있다. 지정한 값을 포함한다. 즉, 이상과 이하를 설정할 수 있다. @Max, @Min은 하나씩 사용할 수도 있지만 data5처럼 한번에 사용하여 범위를 지정할 수도 있다.

 

 

@AssertTrue, @AssertFalse

Assert : (강력히)주장하다. - 구글번역기..

참이라고 주장하는 아이와 거짓이라고 주장하는 아이?

@AssertTrue는 값이 false이면 유효성 검사를 만족하지 못하고, @AssertFalse는 값이 true이면 유효성 검사를 만족하지 못한다. 

 

 

@DecimalMax, @DecimalMin

@Max, @Min과 거의 비슷한데 속성에 inclusive를 써줌으로써 value의 값을 포함시키느냐 마느냐를 결정해줄 수 있다.

즉, inclusive가 ture이면 이상, 이하로서 사용이 가능하고 inclusive가 false이면 초과, 미만으로서 사용이 가능하다.

 

 

@Null, @NotNull

@Null은 값이 들어오면 오류가 발생(항상 널이어야하는 값에 사용)

@NotNull은 값이 들어오지 않으면 오류가 발생(반드시 입력을 받아야 하는 값에 사용)

 

 

@Digits(integer=?, fraction=?)

자릿수를 결정할 수 있다. integer속성은 자연수의 자릿수를 결정하고 fraction속성은 소숫점의 자릿수를 결정한다.

예를 들어,  @Digits(integer=3, fraction=3)인데 data10이 100.1111이면 오류가 발생하겠다. 근데 100이 들어갔다면 소숫점(fraction)은 0이라고 판단되어 오류가 발생하지는 않는다.

 

 

@Parttern(regexp=정규식)

regexp속성에 들어있는 정규식에 위배되면 오류가 발생한다. 예를들어 regexp="[a-zA-Z]*" 라고 선언되어 있으면 소문자 a~z 대문자 A~Z까지만 유효하다.

 

 

 

error_message.properties

 

각 어노테이션에서 발생할 수 있는 에러메세지를 properties파일에 담아서 이 파일을 메세지로 등록하였다.

 

 

Controller

 

Controller에서 @Valid를 써줌으로써 Hibernate Validator를 사용한다. DataBean1이라는 빈 클래스에 대한 유효성 검사를 실행하겠다는 선언이다. (@ModelAttribute는 생략되어있기 때문에 DataBean은 Request영역에 자동으로 담긴다.)

 

properties파일을 message로 등록한 후, jsp에서 위와 같이 form커스텀 태그를 활용하여 사용할 수 있겠다. 

유효성 검사를 통과하지 못하면 properties파일에 등록해주었던 에러메세지들이 출력될 것이다.

 

 

 

 

JSR-380

 

 

많이 사용되는 JSR-380 어노테이션들이다.

 

@NotEmpty

주입된 문자열의 길이가 0이면 오류가 발생한다. 공백도 글자로 인식한다. (스페이스바 3번누르면 길이가 3이라고 인식한다.)

 

 

@NotBlank

주입된 값이 공백을 제거하고 길이가 0이면 오류가 발생한다. (스페이스바 3번누르면 공백이라고 인식한다.)

 


@Positive

양수가 아니라면 오류가 발생한다. (0을 포함하지 않고 1이상의 값.)

 


@PositiveOrZero

0또는 양수가 아니라면 오류가 발생한다. 

 


@Negative

음수가 아니라면 오류발생 (0을 포함하지 않고 -1이하의 값.)

 


@NegativeOrZero

0또는 음수가 아니라면 오류가 발생한다. 

 


@Email

이메일 형식이 아니라면 오류가 발생한다. 중간에 @가 있는지 정도만 확인해준다.

'JAVA > Spring MVC' 카테고리의 다른 글

예외처리  (0) 2020.05.03
Interceptor  (0) 2020.05.03
에러메세지 커스터마이징  (2) 2020.04.30
Spring MVC 유효성검사  (0) 2020.04.30
Message  (0) 2020.04.29

저번 포스팅에서 SpringMVC Validation에 대한 간단한 예제를 살펴보았다. 유효성 검사에서 오류가 있다고 판단되는 항목에 대해서 JSP에서 메세지를 출력하였는데 JSR-303에서 정의한 defaultMessage를 가져와서 출력해주는 것이었다.

우리가 설정한 문자열을 오류메세지로서 출력하기 위해서는 properties파일을 이용한다.

propertise파일에 정의한 변수들은 서버가 동작하는 중에는 절대 변경할 수 없는 값이며, message로 등록하면 JSP에서도 사용할 수 있었다. 그 점을 이용해서 properties파일에서 변수를 불러와서 메세지를 커스텀메시지를 출력할 수 있다.

 

저번 포스팅에서 BindingReust객체를 getAllErrors()를 이용해서 가져온 후, 배열의 첫번째 인덱스를 읽어왔을 때, 

에러종류(어노테이션의 종류).빈 이름.프로퍼티 이름의 형식으로 문자열을 가져올 수 있었다.

 

properties파일에 등록할 변수를 위와 같은 형식으로 message에 등록해줌으로써 유효성 검사에 통과하지 못하여 에러메세지가 출력될 때, properties파일에 사용자가 지정한 데이터를 출력할 수 있도록 해준다!

또 한, 메세지를 이용한 다국어 처리까지 가능해진다.

 

 

빈 클래스의 유효성 검사 정보 설정

 

다음과 같이 DataBean1이라는 빈클래스를 유효성검사 대상 빈으로 등록하고 BindingResult객체를 주입받아서 결과에 오류가 있다면(유효성 검사에 만족하지 않는다면) 값을 입력하는 폼을 다시 불러오게 하였다.

 

기본적인 Validation을 JSP에 출력하는 방법은 Request객체에 담겨있는 errors를 이용하는 것이지만 이번에는 properties파일에 에러메세지를 저장하고 그 파일을 message에 등록한 후, form커스텀의 message태그를 이용하여 해당 에러메세지를 출력해보는 방식으로 활용해 보겠다!!

 

 

error_message.properties

 

codes배열에 첫번째 배열의 인덱스에는 에러종류(어노테이션의 종류).빈 이름.프로퍼티 의 형태로 에러메세지가 저장됨을 저번 예제에서 살펴보았었다. 그부분의 에러를 똑같이 properties파일에 저장하는 것이다. 

DataBean1빈에서 data1프로퍼티의 Size(여기서는 2~10글자수의 문자열)에 유효성검사가 실패하면 오류가 날것이기 때문에 오류메세지를 위와 같이 정의해준다. data2도 마찬가지이다.

 

 

그 후에 이 properties파일을 Message로 등록해주자.

 

 

message로 등록해주었으니 이제 form커스텀 태그를 이용해서 jsp에서도 활용을 할 수 있게 되었다.

 

 

 

 

tags를 사용하기 위해서 jsp에 taglib를 추가해주고, 만약 dataBean1의 data1에 에러가 있으면

<spring:message>태그를 이용하여 위와같이 출력해준다. codes배열의 첫번째 인덱스의 형식으로 properties파일을 등록해주었기 때문에 만약 유효성검사를 통과하지 못하고 error가 발생한다면 우리가 커스텀한 메세지가 출력될 것이다.

 

 

 

유효성 검사의 조건을 만족하지 못하면 위와 같이 커스터마이징한 에러메세지가 출력된다. 

 

 

 

 

그런데, 한가지 문제가 있다.

Controller에서 BindingResult객체를 주입받아서 result.hasErrors()하여 유효성 검사를 만족하지 못하면 폼 화면을(inputData.jsp) 요청하였다. 이렇게 되면 유효성을 만족하지 못한 데이터 뿐만 아니라 만족했던 데이터까지도 input폼에 남아있지 않고 사라진다. 유효성조건을 만족하는 데이터는 사라지지 않게 하려면 어떻게 해야할까??

 

form커스텀 태그의 input태그를 이용하면 자동으로 name값과 id값을 넣어주고, value값을 유지시켜주었다.

그래서 회원수정 폼이나 글 수정 폼에 적합하다고 소개를 했었다!!

그걸 활용해보자.

 

 

 

폼 커스텀 태그를 사용하기 위해서 taglib를 추가해 주었다.

<form:form>태그에 modelAttribute속성에 빈 클래스를 정의해주면 컨트롤러에서 modelAttribute로 넘겨주었던 빈클래스를 주입하여 사용하게 된다. 

<form:input>태그에 path속성을 정의한 빈 클래스의 프로퍼티와 동일하게 설정하면 자동으로 id, name이 path의 값과 동일하게 들어가고 사용자가 입력한 값이 value속성에 들어가게 된다. 

<form:errors>태그의 path속성을 정의한 빈 클래스의 프로퍼티와 동일하게 설정하면 컨트롤러에서 Request에 자동으로 들어갔던 BindingResult객체의 errors값을 이용하여 유효성 검사를 하게 되고, 유효성 검사를 만족하지 못하면 errors의 배열의 첫번째 인덱스의 에러메세지를 출력하게 된다. 에러메세지는 Message로 등록된 properties파일에서 찾아준다.

 

 

즉, 

 

<c:if test="${errors.hasFieldErrors('data1') }">
   <spring:message code="${errors.getFieldError('data1').codes[0]}" /><br/>
</c:if>

 

 

이만큼의 코드를 

 

 

<form:errors path="data1" /><br/>

 

 

이 폼 커스텀 태그 한줄로 대체가 가능하다는 것이다..

유효성 검사를 jsp에서 활용하려면 폼 커스텀 태그를 사용해야 할 것 같다.

'JAVA > Spring MVC' 카테고리의 다른 글

Interceptor  (0) 2020.05.03
JSR-303, JSR-380 어노테이션  (0) 2020.05.01
Spring MVC 유효성검사  (0) 2020.04.30
Message  (0) 2020.04.29
Properties  (0) 2020.04.28

웹 어플리케이션에서 사용자 입력에 대해 유효성을 검사해야하는 경우가 있다. 예를 들어, 회원가입을 한다거나 글을 작성한다거나 하는 경우가 되겠다. 이 때, 작성한 내용을 규칙에 맞게 잘 작성을 하였는가에 대한 검사를 유효성 검사라고 한다.

 

이러한 유효성검사는 JavaScript에서 브라우저가 서버로 요청을 보낼 때 먼저 확인을 하는 경우도 있으나 SpringMVC에서도 확인을 할 수 있다. 클라이언트가 보낸 테이터를 서버에서 먼저 확인을 하고 저장을 할지 말지를 결정하겠다는 것이다. 

빈에 데이터가 입력될 때 어떤검사를 할것인지 어노테이션으로 지정하고 지정된 어노테이션의 조건에 맞지 않으면 개발자에게 입력값에 오류가 있다는 정보를 전달한다. 즉, 클라이언트에서 넘어온 데이터 자체를 검사한다기 보다는 일단은 값을 빈에 주입을 하고, 들어간 값을 검사해서 올바른 규칙으로 들어왔는지에 대한 검사를 한다.

 

 

SpringMVC는 JSR-303, JSR-380 이라는 규격의 유효성 검사 라이브러리를 사용할 수 있다. 

 

먼저 라이브러리를 추가해보도록 하겠다. 

 

 

mvnrepository사이트에서 Bean Validation이라고 검색하면 다음과 같은 javax.validation api를 찾을 수 있다. 

pom.xml에 추가해주었다.

 

 

 

hibernate validator라는 라이브러리도 추가해주어야한다. hibernate validation은 변수에 주입된 값을 실제로 검사하는 코드가 구현된 검사기이다. 가장 많이 사용하는 validator라고 한다..

 

 

 

 

이제 간단하게 유효성 검사를 해보겠다.

 

 

먼저 주입받는 빈에 어노테이션을 이용하여 조건을 정해주어야 한다. 

@Size는 min값과 max값 사이의 글자 수 만큼만 주입할 수 있다는 의미이다. (data1에는 글자수 2~10의 문자열)

@Max는 정해진 숫자 이하의 값만 주입할 수 있다는 의미이다. (data2에는 100이하의 정수)

더 많은 어노테이션이 있지만 다음 포스팅에서 더 자세하고 다양하게 예제실습을 해보도록 하겠다.

 

 

 

Controller에서 @Valid를 설정하여 유효성 검사를 실시할 수 있다. 매개변수에 어노테션은 붙여주면 설정해준 빈 클래스에서 조건 어노테이션에 맞게 유효성 검사를 진행한다.

유효성 검사의 결과는 BindingResult객체를 주입받아서 확인이 가능하다. BindingResult객체에는 유효성 검사에 위배된 정보들이 들어가 있다. 이 정보들은 Request 영역에 errors라는 이름으로 넘겨지게 된다. 후에 JSP에서 활용하는 코드에서 살펴보자.

 

result라는 이름의 BindingResult변수를 이용하여 유효성 검사에 위반된 부분을 알 수 있다.

hasErrors()를 이용하여 만약에 오류가 발생하였다면(위반된 부분이 있다면), 그 모든 오류들을 ObjectError객체에 담아서 출력할 수 있다. getAllErrors메소드는 List형의 반환값을 가진다.

 

 

 

위와 같이 출력하면 다음과 같은 결과를 얻을 수 있다. 여기서 한개 더 얻을 수 있는 정보는 바로 getCodes에 관한 부분이다. 

 

 

오류결과를 모두 가져와 출력해주는 코드에서 String배열로 obj.getCodes()를 이용하여 에러 코드들만을 받아온 부분을 볼 수 있다. 저 배열에 담겨 있는 모든 코드들을 실행 해보겠다.

 

 

 

어떤 에러가 났고, 어떤 빈에서 났고, 어떤 프로퍼티에서 났고.. 이러한 정보들이 여러개 나오는것을 알 수 있었다. 

우리는 이중에서 첫번째 배열을 잘 보자. 

 

 

에러종류(어노테이션종류).빈이름.프로퍼티이름  

 

 

이러한 규칙으로 출력되었다. 이 첫번째 인덱스에 들어간 정보들에서 어떤 빈에서 어떤 프로퍼티가 어떤 에러가
났는지 바로 알 수 있기 때문에 우리는 이 첫번째 인덱스를 나중에 properties파일에 위와 같은 양식으로 집어넣어 code[0]으로 값을 가져와 사용할 수 있다. 이 예제는 다음포스팅에서 살펴보도록 하자.

 

 

 

 

이번에는 이 유효성검사의 오류결과들을 JSP에서 사용해보자.

아까 위에서 잠깐 이야기를 했지만, BindingResult객체를 이용하면 오류정보들이 Request영역에 errors라는 이름으로 넘겨지게 된다. 우리는 그것을 JSP에서 사용하면 된다. 

 

 

 

errors를 가져오려면 spring 태그를 이용해야하기 때문에 taglib를 추가해주었다. 오류가 나면 그 오류 메세지를 가져오라는 조건문을 작성해야 하기 때문에 jstl도 사용한다. 

 

 

 

 

조금 복잡하지만 일단은 가장 기본적인 방법으로 에러메세지를 출력하는 방법을 사용해보았다. 앞으로 에러메세지를 커스터마이징 하는 부분에서 위의 코드는 더욱 간단해질 것이다.

<spring:hasBindErrors> 태그의 name을 빈 클래스로 설정해주어서 빈클래스의 유효성검사에 error가 있으면 이 커스텀 태그에 들어오게 된다. <c:if test>에서 Request영역에 있는 errors를 가지고 온다. 빈 클래스의 data1프로퍼티에 오류가 있을 때, 오류메세지를 받아와서 그중에서 defaultMessage만 출력하겠다는 이야기이다.

여기서 defaultMessage는 위의 결과창에서 보았던 메세지를 말한다.

 

 

data1의 문자열 길이가 2~10글자수가 넘어가거나, data2의 정수가 100이 넘어가게 되면 오류메세지를 출력한다.

'JAVA > Spring MVC' 카테고리의 다른 글

JSR-303, JSR-380 어노테이션  (0) 2020.05.01
에러메세지 커스터마이징  (2) 2020.04.30
Message  (0) 2020.04.29
Properties  (0) 2020.04.28
SpringMVC에서 Cookie 사용하기  (0) 2020.04.28

properties는 서버가 동작하는 도중에 절대로 변하지 않는 값으로 properties파일을 만들어서 따로 관리했었다.

그러한 properties에 설정한 값들을 JSP에서 사용하려면 몇가지 설정이 필요하다.

properties파일을 message에 등록하게 되면 이 데이터를 JSP에서도 사용할 수 있으며 다국어 처리도 할 수 있도록 지원한다.

 

 

 

MessageSource

 

MessageSource객체를 이용해서 properties 파일을 등록해주면 Message로 등록할 수 있다.

이 때, 일정 시간마다 한번씩 갱신되는 ReloadableResourceBundleMessageSource를 이용한다. 원래 properties로 지정하면 서버가 가동되는 동안에는 절대로 값을 변경할 수 없는데 ReloadableResourceBundleMessageSource를 이용하면 서버를 중지하지 않더라도 properties를 변경하면 갱신되서 사용가능하게 한다.

message를 등록하는 방법은 Spring설정파일을 Java에서 등록한 프로젝트와 xml파일에서 등록한 프로젝트의 방법이 약간 다르다. 사용하는 방법은 똑같으니 설정하는 것만 알아보도록 하자.

 

 

 

 

1. Java설정파일

 

 

ReloadableResourceBundleMessageSource형 메소드를 빈으로 등록을 해주어야 한다. (ServletAppContext.java에!)

properties를 한개반 등록한다면 setBasename을 사용하고 여러개라면 setBasenames를 사용해준다. 그리고 주의할 점은 properties의 경로를 적을 때 확장자명은 생략해서 적어주어야 한다.

 

 

 

2. xml설정파일

 

 

xml 설정파일(servlet-context.xml)에 등록하는 방법은 다음과 같다. 

ReloadableResourceBundleMessageSource를 클래스로 등록해주고, 프로퍼티의 이름을 basename으로 등록해서 value에 경로를 넣어준다. 여러개라면 프로퍼티의 이름을 basenames로 등록해주고 안에 list형식으로 value를 등록해주면 된다. 경로를 지정할 때 역시 확장자명을 빼고 써주어야 한다.

Java와 다른점은 xml은 등록한 메세지 소스 객체를 통해서 properties파일에 접근할 수 있는 MessageAccessor를 지정해주어야 한다. MessageSourceAccessor 클래스의 빈을 등록해주고 그 빈의 생성자에 위에서 만든 messageSource빈을 주입해주면 된다.

 

 

 

 

3. Controller에서 사용하는 방법

 

 

1번과 2번처럼 작업을 해주면 properties가 message로 등록이 된 것이다. 이 message를 사용하기 위해서 ReloadableResourceBundleMessageSource를 주입받아서 사용한다. 이때 Locale을 받으면 다국어 처리가 가능하다.

 

위와 같이 getMessage("aaa.a1", null, null) 하여 properties파일에 aaa.a1이라는 이름의 변수의 값을 가져온다. 

매개변수를 총 3개 받는데 아래서 한개씩 설명하도록 하겠다. 

첫번째 매개변수는 변수의 이름과 맞는 값을 받아올 때 사용한다. 

 

 

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<body>
   <h1> result </h1>
   <h3> aaa.a1 : <spring:message code="aaa.a1" /> </h3>
   <h3> ccc.c1 : <spring:message code="ccc.c1" /> </h3>
</body>

 

 

JSP(View)에서 taglib를 선언하여 Form커스텀 태그를 이용하여 message를 사용할 수 있다. 

<spring:message>태그code라는 설정을 message에 등록된 properties의 변수이름으로 선언해주면 해당 변수의 값을 출력하는 결과를 얻을 수 있다.

 

 

 

 

 

 

이번엔 getMessage의 두번째 매개변수의 활용이다.

properties파일에서 위와 같이 'aaa.a3 = 나이는 {0}이고 이름은 {1}입니다.' 방식으로 {0}, {1}과 같이 선언해주었다.

properties파일은 서버가 동작하는 도중에 절대 바뀔 수 없는 값이다. 하지만 두번째 매개변수를 이용해서 해당 변수에 값을 넣어줄 수 있다. 문자열 배열을 선언하고 그 배열을 두번째 매개변수에 넣어준다.

이렇게 하면 message에 등록된 properties파일의 변수에 값을 넣어줄 수 있다. JSP(View단)에서 사용하려면 Model을 이용해서 Request로 넘겨주어야 한다!

 

 

<body>
   <h1> result </h1>
   <h3> aaa.a1 : <spring:message code="aaa.a1" /> </h3>
   <h3> ccc.c1 : <spring:message code="ccc.c1" /> </h3>
   <h3> ccc.c1 : <spring:message code="aaa.a3" arguments="${args}"/> </h3>
</body>

 

 

 

Form커스텀 태그에서 사용할 때에는 다음과 같이 arguments라는 속성에 Request영역으로 넘겨주었던 문자열 배열의 값을 넣어주면 된다. 

 

 

 

 

 

 

 

 

3번째 매개변수의 활용이다. 이 매개변수는 다국어 처리를 위한 것이다. 사용하고자 하는 메소드에 Locale클래스를 매개변수로 받고 그 변수를 세번째 매개변수에 넣으면 실행중인 웹 브라우저의 언어를 기반으로 값을 지정하여 출력해준다.

아무것도 설정하지 않고 출력하면 한국어라는 의미로 ko라고 출력이 된다. 

 

 

웹 브라우저의 (필자는 크롬에서 설정) 언어를 영어로 바꾸어 보았다. 

 

 

다음과 같이 en_US라고 나오는것을 볼 수 있었다. 이를 활용해서 원하는 값을 다국어 처리를 할 수 있다. 

 

data1_ko.properties
data1_en.properties

 

data1_ko.properties, data1_en.properties 라는 이름으로 properties파일을 두개 만들었다. 각각의 프로퍼티파일에는 같은 이름의 변수 lang.a1이 선언되어있지만 값은 각각 한국어, english로 상이하다.

이렇게 하면 한국어인경우 ko파일을, 영어인경우 en파일을 자동으로 찾아주게 된다.

'JAVA > Spring MVC' 카테고리의 다른 글

에러메세지 커스터마이징  (2) 2020.04.30
Spring MVC 유효성검사  (0) 2020.04.30
Properties  (0) 2020.04.28
SpringMVC에서 Cookie 사용하기  (0) 2020.04.28
Spring MVC에서의 빈 관리 (ApplicationScope)  (0) 2020.04.28

애플리케이션을 개발할 때 프로그램 실행 중 절대 변하지 않는 값들이 있을 수 있다. SpringMVC에서는 이러한 값들을 properties파일에 작성하고 이를 가져다 사용할 수 있도록 제공되고 있다.

 

 

properties파일은 WEB-INF파일 아래에 폴더를 만들어서 다음과 같이 만들어 주었다.

WEB-INF아래에 만들면 어디에 놓으나 상관은 없지만 properties파일의 종류가 여러개 있을수 있기 때문에 폴더로 묶어서 보통 관리를 한다.

 

data1.properties파일이다. 이렇게 설정하면 aaa.a1은 이제 바꿀 수 없고, 컨트롤러에서 손쉽게 가져다 쓸 수 있다.

aaa.a2는 문자열1 이라는 String값인데, 처음에 properties파일을 만들고 '문자열1' 이라고 입력하면 유니코드의 형태로 자동으로 저장이 된다. 유니코드로 저장되면 우리가 나중에 유지보수를 하거나 할때.. 어려움이 있을 수 있다.

 

그래서 Property Editor를 설치해주겠다.

이클립스에서 Help > Install New SoftWare에 들어가준다.

 

 

Add버튼을 눌러서 

Name은 Property Editor, Location은 http://propedit.sourceforge.jp/eclipse/updates 라고 넣어주고 Add해주면 된다.

이클립스가 재시작되고 자동으로 Property Editor가 설치되며, 설치 이후에는 properties파일에 한글이 유니코드형식이 아닌 한글로 나오게 된다.

 

 

 

@Controller와 함께 @PropertySource를 써줌으로써 properties파일을 가져다가 사용할 수 있다.

만약 사용하고자하는 properties파일이 여러개라면?

 

 

 

@PropertySource에 value속성을 이용해서 배열처럼 여러개를 써주어도 되고, 

@PropertySources아래에 @PropertySoruce를 여러개 작성하여 명시해주어도 상관이 없다.!

 

'JAVA > Spring MVC' 카테고리의 다른 글

Spring MVC 유효성검사  (0) 2020.04.30
Message  (0) 2020.04.29
SpringMVC에서 Cookie 사용하기  (0) 2020.04.28
Spring MVC에서의 빈 관리 (ApplicationScope)  (0) 2020.04.28
Spring MVC에서의 빈 관리 (SessionScope)  (0) 2020.04.27

+ Recent posts