애플리케이션을 개발할 때 프로그램 실행 중 절대 변하지 않는 값들이 있을 수 있다. 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

쿠키.. 세션... 인터넷을 사용하다보면 꽤 많이 들어보는 단어이다. 쿠키란 대체 무엇일까? 

 

강의를 통해 공부하면서 블로그에서 정보를 찾다가 아주 잘 정리가 되어있는 블로그를 찾아서 조금 인용을 하고자 한다.

 

 

쿠키란?

  • 쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일입니다.

  • 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다는 특징이 있습니다.

  • 쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 참조합니다.

  • 클라이언트에 300개까지 쿠키저장 가능, 하나의 도메인당 20개의 값만 가질 수 있음, 하나의 쿠키값은 4KB까지 저장합니다.

  • Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있습니다.

  • 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 전송합니다.

출처 : 쿠키와 세션 개념 by 라이언곰돌이푸, https://interconnection.tistory.com/74

 

 

쿠키는 사용자 웹 브라우저에 저장되는 데이터이며 서버에 저장되는 데이터가 아니다.

요청이 발생했을 때 웹 브라우저는 쿠키에 저장된 정보를 서버에 전달하게 된다. 이때 쿠키 정보까지 같이 묶어서 보낸다. 응답결과로 쿠키정보가 전달이 되면 웹 브라우저가 쿠키에 저장하게 된다. 쿠키는 사용자 브라우저에 저장되는 것이므로 브라우저가 전달해 줄 때만 쿠키정보를 사용할 수 있다. 

 

 

서버측 코드로 쿠키에 데이터를 저장할 수 있는 방법은 없다. 브라우저로 보낼 응답결과에 저장할 쿠키정보를 담아 보내면 브라우저에 의해 웹 브라우저에 쿠키가 저장되게 된다. 

 

 

서블릿, JSP에서는 어떻게 쿠키를 사용했었는지 한번 생각해보자.

 

 

쿠키를 저장하기 위한 코드이다. 우선 쿠키는 문자열 데이터만 저장이 가능하기 때문에 문자열 데이터를 집어 넣어야하고, 한글 데이터를 받기 위해서는 UTF-8로 인코딩을 해주어야 한다. (받을 때는 디코딩도 따로 해주어야 한다.)

 

웹 브라우저에게 쿠키를 담아서 응답결과로 보내야하기 때문에 response객체를 매개변수로 사용한다.

data1과 data2에는 각각 문자열1, 문자열2 라는 문자열을 인코딩하여 담아주고 그 문자열 변수를 쿠키에 담아준다.

setMaxAge를 이용하여 쿠키의 유효시간을 정해준다. 유효시간이 정해지면 브라우저가 종료되어도 쿠키데이터는 사라지지 않는다. 그 후, addCookie하여 쿠키를 response객체에 담아준다.

 

 

크롬에서 F12를 누르면 다음과 같이 개발툴을 볼 수 있다. Application탭을 클릭하면 왼쪽에 Cookies라는 쿠키데이터 목록이 있는 것을 볼 수 있다. 현재 이 브라우저에는 아직 쿠키데이터를 요청하지 않았기 때문에 아무것도 안보인다.

위해서 해준 쿠키데이터와 함께 브라우저를 요청해보면,

 

 

이렇게 서버에서 Response객체에 넣어서 보내준 Cookie객체가 잘 나오는 것을 볼 수 있다. 

인코딩을 해서 보내주었기 때문에 Value는 인코딩이 된 모습으로 보인다! 저 Value를 이용하기 위해서는 인코딩을 하여야 한다.

이번에는 웹 브라우저가 가진 Cookie를 가져와 보겠다.

 

 

 

Servlet, JSP에서는 쿠키정보를 받아올 때 특정 쿠키 몇개만 선별적으로 읽어낼 수 없다...

위와 같이 우선 쿠키배열로 쿠키데이터 전부를 받아온 후, 반복문을 이용해서 쿠키의 이름을 비교하여 사용할 쿠키를 뽑아내는 작업을 거쳐야 한다. 물론 한글사용을 위해 인코딩한 값으로 쿠키가 저장되어 있기 때문에 쿠키를 사용할 때에도 디코딩하여 쿠키를 사용해야 한다.

 

Spring MVC에서는 쿠키를 받아오는 작업을 훨씬 쉽게 할 수 있는 어노테이션을 제공한다.

 

 

 

바로 @CookieValue어노테이션이다. 이 어노테이션을 사용하면 원하는 쿠키만을 이름으로 가져와서 주입해주며,

디코딩도 자동으로 해주기 때문에 따로 작업해주지 않아도 된다.

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

Message  (0) 2020.04.29
Properties  (0) 2020.04.28
Spring MVC에서의 빈 관리 (ApplicationScope)  (0) 2020.04.28
Spring MVC에서의 빈 관리 (SessionScope)  (0) 2020.04.27
Spring MVC에서의 빈 관리 (RequestScope)  (0) 2020.04.27

처음 요청이 발생해서부터 응답결과가 전달될 때까지의 범위를 RequestScope, 

브라우저에 의해 최초의 요청이 발생되고 브라우저가 종료될 때까지의 범위를 SessionScope,

서버가 가동될 때부터 서버가 종료되는 시점까지의 범위를 ApplicationScope라고 부른다!!

 

ApplicationScope동안 사용할 수 있는 메모리영역이 만들어지며 ServletContext라는 클래스 타입의 객체로 관리된다.

ServletContext에 저장된 데이터나 객체는 서버가 종료되기 전까지 웹브라우저에 관계없이 동일한 메모리 공간을 사용하게 된다. 즉, 서버만 종료되지 않는다면 다른 브라우저에서도 같은 메모리공간을 사용할 수 있다는 의미이다.

 

 

 

1. ServletContext

 

 

ServletContext는 HttpServletRequest에서 받아올 수 있다. 위와 같이 ServletContext형 변수를 만들어서 받아온 후에 사용할 수 있다. Request영역이나 Session영역과 크게 다를바는 없다. ServletContext를 사용한다는것만 알아두도록 하자.

 

 

 

ServletContext는 타입을 통한 주입으로 Controller에서 주입을 받을 수 있다.

위와 같이 @Autowired로 ServletContext를 자동주입 받아 오면 매개변수로 HttpServletRequest를 받아오지 않아도 ServletContext를 이용해서 Application영역의 메모리공간을 사용할 수 있다. 

 

 

 

 

 

2. ApplicationScope 빈 주입

 

빈을 정의할 때 ApplicationScope로 정의하면 서버가 가동될 때 자동으로 주입된다. 주입된 빈은 주입만 이루어지는 것이므로 Application영역에는 저장되지 않는다. (RequestScope, SessionScope와 동일하다.)

 

 

자바 빈 설정파일에 다음과 같이 @ApplicationScope를 사용해서 빈을 2개 정의해주었다. 위의 bean1메소드는 타입을 통한 빈 주입에 사용될 것이고 bean2메소드는 이름을 통한 빈 주입에 사용될 것이다.

 

 

타입을 통한 주입

 

이름을 통한 주입

 

각각 타입을 통한 주입과 이름을 통한 주입이다. 위에서 설명하였듯, Application영역에 직접 주입되는 것이 아니기 때문에 View단에서 사용하려면 Model을 사용하여 현재 빈을 Request영역에 넣어서 보내주어야 한다.

 

 

<body>
   <h1> result </h1>
   data1 : ${requestScope.application.data1}<br/>
   data2 : ${requestScope.application.data2}<br/>
</body>

 

 

Application영역이 아닌 Request영역에 잘 들어갔는지 (사실 Model로 넘겨주었으니 당연한것.) 확인하기 위해 requestScope를 앞에 붙여주었다. 결과는 잘 나왔다.

 

만약 빈을 xml에서 만들어주었다면?

 

root-context.xml에 위와 같이 설정해 주면 되겠다.

 

 

 

 

 

다음으로는 컨포넌트 어노테이션을 이용한 빈 주입을 살펴보도록 하자.

 

 

빈 클래스에 @Component와 @ApplicationScope을 붙여준다. 그리고 컴포넌트 스캔을 설정해주면 된다.

 

자바 빈 설정파일의  ComponentScan
servlet-context.xml의 ComponentScan

 

자바 빈 설정파일과 xml의 컴포넌트 스캔 등록방법은 다음과 같다. bean객체가 있는 패키지를 등록해주면 된다.

@Component는 기본적으로 타입을 통한 객체 자동주입이 때문에 위의 @Autowired를 사용한 예제와 똑같이 해주면 된다.

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

Properties  (0) 2020.04.28
SpringMVC에서 Cookie 사용하기  (0) 2020.04.28
Spring MVC에서의 빈 관리 (SessionScope)  (0) 2020.04.27
Spring MVC에서의 빈 관리 (RequestScope)  (0) 2020.04.27
Redirect와 Forward  (0) 2020.04.24

session이 뭘까? 

브라우저가 최초로 서버에 요청을 하게 되면 브라우저당 하나씩 메모리 공간을 서버에서 할당하게 된다. 이 메모리영역은 브라우저당 하나씩 지정되고 요청이 새롭게 발생하게 되더라도 같은 메모리 공간을 사용하게 된다.

이러한 공간을 session이라고 한다. session은 브라우저가 종료될 때까지 서버에서 사용이 가능하다.

 

SessionScope는 브라우저가 최초 요청을 발생시키고 브라우저를 닫을 때 까지의 영역을 가리킨다. SessionScope에서는 Session영역에 저장되어 있는 데이터나 객체를 자유롭게 사용할 수 있다. 

 

 

 

1. HttpSession

 

 

Session은 새로운 요청이더라도 브라우저만 유지되면 보존되는 공간이다.

Request였다면 새로운 요청을 할 때마다 새로운 객체가 생성되어 위와 같이 정의한다면 sessionScope메소드의 Request객체와 result메소드의 Request객체는 달랐을 것이다. (그래서 브라우저에게 요청하기 전에 서버단에서 데이터를 사용하기 위해서 forward를 이용함으로써 같은 객체를 사용할 수 있었다!)

 

Session은 같은 웹 브라우저 내에서의 요청이라면 sessionTest.jsp에서 사용하는 객체나 result.jsp에서 사용하는 객체가 같을 것이다.

 

또 한가지, SpringMVC에서는 HttpSession이라는 클래스를 제공한다. 위에 주석처리 되어 있는 코드를 보면 우리는 JSP Servlet를 이용할 때에도, Request를 이용하여 데이터를 사용할 때에도 이와 같은 방법으로 request.getSession()을 통해 세션을 가지고 왔고 그 세션에 저장되어 있는 객체를 getAttribute를 이용하여 가져와서 사용하였다.

HttpSession을 이용하면 조금 간단하게 매개변수로 session을 받아와서 사용할 수 있다. 

 

 

 

 

2. Redirect와 Forward

 

그렇다면 Redirect와 Forward는 Session객체에 영향을 줄까? 결론부터 말하면 영향을 주지 않는다. 브라우저만 바뀌지 않으면 session영역은 유지되기 때문이다.

 

 

위와 같이 Redirect요청을 반환하는 메소드 한개와 Forward요청을 반환하는 메소드 한개를 각각 정의 한후 result메소드에는 session에 저장된 data1을 출력할 수 있도록 해보았다.

결과는 아무 영향을 받지 않고 각각의 결과를 잘 출력하는 것을 볼 수 있었다. 

 

 

 

 

3. @SessionAttribute

 

Session영역에 저장되어 있는 객체를 사용할 때 메소드의 매개변수로 @SessionAttribute를 설정하면 Session영역에 설정되어 있는 빈을 주입받을 수 있다. 

 

 

@SessionAttribute("빈이름")은 빈이름으로 만들어져있는 객체를 주입받는것이지 새로운 객체를 주입하여 빈 이름으로 session에 저장되는 것은 아니다. @ModelAttribute랑은 좀 다르다!

"data1"이라는 이름으로 등록되어 있는 session객체를 찾아서 DataBean1 bean에 넣어주는 것이다. 

getAttribute대신 매개변수로서 받을 수 있다고 간단하게 생각하면 될 것 같다. 

 

 

 

 

4. @SessionAttributes

 

3번의 @SessionAttribute와는 조금 다르다..! 

@ModelAttribute의 경우 @ModelAttribute를 통해 주입 받는 빈은 자동으로 Request영역에 저장이 되고 Request 영역으로부터 주입을 받게 된다. 이때 @ModelAttribute를 통해 주입을 받는 빈을 @SessionAttributes로 지정해주면 Request영역이 아닌 Session영역에 저장이 되고 Session영역으로부터 주입을 받을 수 있다.

 

여기서 주의할 점은 @ModelAttribute를 활용하여 객체를 생성해 반환하는 메소드를 반드시 작성해 주어야 한다는 것이다.

 

 

위와 같이 @SessionAttributes("session")이라고 등록하고 @ModelAttribute("session")이라고 등록을 하면, @ModelAttribute에서 session이라는 이름으로 세션을 주입하면, 해당 이름과 같은 SessionAttributes를 찾아서 Request영역이 아닌 Session영역에 저장을 해준다.

 

 

이렇게 session이란 이름으로 ModelAttribute를 사용하면 @SessionAttributes에 의해서 Session영역에 저장이 되게 되고, 주소와 매핑되어져 있는 메소드가 실행이 될때 빈 객체에 주입을 해주게 된다. 

 

 

Session영역에 저장된것을 확인하기 위해서 sessionScope를 사용해보았다.

위와 같이 View를 코딩하면 정상적으로 데이터 값이 출력되는 것을 알 수 있었다.

 

 

 

 

5. SessionScope 빈 주입

 

타입을 통한 주입과 이름을 통한 주입을 한번에 예제로 해보도록 하겠다.

 

자바 빈 설정파일에 위와 같이 빈을 두개 설정해주었다. 한개는 타입을 기반으로 사용하기 위해 빈을 설정해주었고, 한개는 byname이라는 이름을 기반으로 사용하기 위해 빈을 설정해주었다.

 

타입을 통한 주입

 

 

이름을 통한 주입

 

타입을 통한 주입은 @Autowired를 사용하여 빈을 주입해주었고, 이름을 통한 주입은 @Resource(name="")을 사용하여 빈을 주입해주었다. 두가지 사용법은 동일하다. 

주입된 빈은 주입만 이루어진 것이므로 session영역에는 저장되지 않는다. View에서 사용하려면 Model을 이용해야 한다.

 

 

 

xml 파일에 빈을 등록할때는 위와 같이 해주면 되겠다.

 

 

 

 

 

 

이번에는 컴포넌트 어노테이션을 이용해서 주입을 할때에는 session을 어떻게 사용하는지 해보자.

 

 

@Component와 @SessionScope를 빈 클래스에 위와 같이 선언해준다. 그리고 컴포넌트 스캔을 설정해주면 된다.

 

 

자바 빈 설정파일의 ComponentScan
servlet-context.xml의 ComponentScan

 

자바 빈 설정파일과 xml의 컴포넌트 스캔 등록방법은 다음과 같다. bean객체가 있는 패키지를 등록해주면 된다.

@Component는 기본적으로 타입을 통한 객체 자동주입이 때문에 위의 @Autowired를 사용한 예제와 똑같이 해주면 된다.

 

 

 

 

 

 

그. 런 .데.

 

 

xml파일에서 빈을 등록해주면, 오류가 난다... 왜그럴까?

SessionScope는 웹 브라우저가 최초 요청을 보낼 때 빈 객체가 주입되게 된다. 그런데 xml방식같은 경우에는 서버가 가동될 때 무조껀 주입을 먼저 시도하려고 한다. xml을 로딩할 때 객체가 바로 생성되도록 한다는 뜻이다. 그래서 오류가 난다.

 

타입을 통한 자동주입(@Autowired)를 할 때, @Lazy를 해주면 (xml파일에 lazy-init="true"해주어도 되겠다.) 로딩과 동시에 객체를 바로 생성하지 않고, 객체를 가져올 때 주입을 시도한다.

즉, @RequestScope의 경우 새로운 요청이 발생하였을 때 주입을 시도하기 때문에 오류를 피할 수 있고,

@SessionScope의 경우도 웹 브라우저가 최초 요청을 보낼 때 주입을 시도하기 때문에 오류를 피할 수 있다.

 

 

 

 

 

 

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

SpringMVC에서 Cookie 사용하기  (0) 2020.04.28
Spring MVC에서의 빈 관리 (ApplicationScope)  (0) 2020.04.28
Spring MVC에서의 빈 관리 (RequestScope)  (0) 2020.04.27
Redirect와 Forward  (0) 2020.04.24
Form 커스텀 태그  (0) 2020.04.24

SpringMVC에서 빈을 생성되는 시점과 소멸되는 시점에 대한 설정을 Scope를 이용하여 할 수 있다. 

Spring Core에서 Scope는 객체를 소멸시키지 전까지 한개의 객체만을 생성하는 SingletongetBean하여 빈을 생성할 때마다 새로운 객체를 생성하는 prototype이 있었다.

SpringMVC에서는 Request, Session, Application을 추가로 제공한다.

 

먼저 RequestScope에 대해서 알아보자. 

 

 

 

 

1. RequestScope

 

request객체에 대해 조금 생각을 해보자. 웹 브라우저에 의해 새로운 요청이 발생하면 브라우저는 서버에 요청에 관련된 정보를 전송하게 된다. 이를 받은 서버는 브라우저가 보낸 요청 정보들을 보관하기 위해서 HttpServletRequest객체를 생성하여 요청 정보를 담아두게 된다. 요청정보가 담겨 있는 HttpServletRequest객체는 응답결과가 브라우저로 전송될 때까지 유지가 되며 사용이 가능하다!

 

새로운 요청이 발생하여 응답결과가 브라우저로 전달 될때까지 요청정보가 담겨 있는 Request객체를 사용할 수 있다. 이러한 사용범위를 RequestScope라고 부른다. HttpServletRequest객체에는 개발자가 필요에 의해 데이터나 객체를 저장할수 있고 RequestScope내에서 사용이 가능하다.

 

 

 

    1.1 HttpServletRequest 사용

 

 

위와 같이 request객체를 활용할 수 있었다. requestScope 메소드를 보면 result메소드로 forward를 하였다. 만약 응답결과로 redirect를 쓴다면 request객체를 웹 브라우저로 전달하면서 request객체는 소멸되고 redirect된 메소드에서 request객체는 새로 생성된다. forward하면 아직 응답결과를 브라우저로 전달하지 않았기 때문에 request객체가 소멸되지 않아서 출력을 할 수 있다. 물론, View에서도 Attribute로 담은 객체를 사용할 수 있다!

 

<body>
   <h1> result </h1>
   data1 : ${data1}
</body>

 

 

이런식으로!!

 

 

 

 

    1.2 Model사용

 

Model을 사용하는 방법도 크게 다르지 않다. 다만 Model을 사용하여 포워딩을 했는데 받는 result메소드에서는 왜 Model로 받지 않고 HttpServletRequest를 이용하여 받았는지 의문이 들 수 있다.

 

model.addAttribute하면 Model에 저장되는 것이 아니라 Request객체에 저정하는 것이다. 그렇기 때문에 받을 때도 HttpServletRequest를 이용해서 받았다. 물론, Request영역에 저장한 것이기 때문에 View에서도 활용이 가능하다.

 

 

<body>
   <h1> result </h1>
   data1 : ${data1}
</body>

 

 

 

    1.3 ModelAndView사용

 

ModelAndView도 Model과 마찬가지로 사용하면 되겠다. ModelAndView예제에서는 클래스자체를 포워딩을 해보자.

 

 

UserDataBean이라는 POJO클래스를 만들어서 활용해보자. 저 클래스는 빈으로 등록하여서 클라이언트가 값을 요청하면 매개변수로 받아서 활용할 수도 있겠다. 그냥 예제니깐.. 이렇게 보았다. 

홍길동, qwer이라는 값을 프로퍼티에 세팅해주고, addObject를 이용해서 "bean"이라는 이름으로 모델에 담은 후 result로 forward를 해주었다. 

Model과 마찬가지로 MoodelAndView도 MoodelAndView객체가 저장되어 넘어가는 것이 아니라, Request객체에 저장을 하는 것이다. 그러므로 포워딩된 result메소드에서 HttpServletRequest를 이용하여 받으면 이용할 수 있다. 

 

 

<body>
   <h1> result </h1>
   username : ${bean.userName }
   userid : ${bean.userId }
</body>

 

View에서도 이렇게 이용할 수 있겠다. 

 

 

 

    1.4 @ModelAttribute 사용

 

 

@ModelAttribute를 통해서 주입받은 객체는 Request영역에 자동으로 저장이 된다. 만약 위와 같이 ModelAttribute를 포워딩했다면 ModelAttribute로 받는 것이 아니라 HttpServletRequest로 받아야 한다. 넘겨준 곳에도 ModelAttribute가있다면 새로운 객체가 주입되고, 덮여 쓰이게 되어 다른 빈 객체가 저장된다. ModelAttribute를 쓸때에도 역시 HttpServletRequest를 써주자. 

 

<body>
   <h1> result </h1>
   username : ${bean.userName }
   userid : ${bean.userId }
</body>

 

 

 

 

 

 

 

2. RequestScope 빈 주입

 

이제 본격적으로 RequestScope를 사용해보자.

공통적으로 이 POJO클래스를 빈으로 등록하여 사용할 것이다. Java Configuration 파일과 Xml파일에 빈을 등록하는 어노테이션과 속성이 약간씩 차이가 있어서 예제마다 다르게 설정을 한것을 설명해보겠다.

 

 

 

    2.1 @Autowired - 타입을 통한 주입

 

자바 빈 등록파일이다. @Bean과 함께 @RequestScope를 사용해줌으로써 이 빈의 scope는 request로 설정해준다.

@RequestScope로 지정하면 이 빈 객체는 새로운 요청이 발생되었을 때 빈이 주입된다.

예를 들어, forward는 새로운 요청을 하는 것이 아니기 때문에(브라우저에게 새로운 요청을 하는것이 아닌 서버단에서 전달하는 것) 원래 있는 빈을 그대로 이용하게 되겠다. 다른 빈 객체가 새롭게 주입되지 않는 이상 객체는 계속 유지가 된다. 

 

@Autowired를 사용하여 타입을 통한 주입을 해주었다. @Autowired을 통해 빈을 등록해주는 순간, 새로운 요청이 발생한 것이기 때문에 DataBean1타입의 빈 객체가 등록이 되고, 새로운 빈 주입이 되지 않는 이상 저 빈 객체는 계속 유지가 될 것이다!!

@RequestScope는 '새로운 요청이 발생하면 빈을 주입하겠다.' 라는 의미이지 Request에 저장을 하는 것은 아니다. 그러므로 View단에서는 바로 사용할 수 없고 Model을 이용하여 넘겨주어야 한다.

 

 

<body>
   <h1> result </h1>
   data1 : ${bean.data1 }
   data2 : ${bean.data2 }
</body>

 

 

만약, 빈을 Java가 아니라 xml파일에서 등록한다면??

 

이렇게 해주면 되겠다. 

 

 

 

 

 

 

 

    2.2 @Resource(name="빈 이름") - 이름을 통한 주입

 

자바 빈 등록파일에 다음과 같이 빈이 이름으로서 등록이 되어 있다.

 

 

 

그러면 @Resource를 이용해서 이름으로 등록된 빈을 받아주면 되겠다. 2.1과 다를건 없다. 빈에는 @RequestScope가 설정되어 있기 때문에 새로운 요청이 발생될 때 빈이 주입된다. 또한, Request영역에는 저장이 안되기 때문에 Model을 사용해야지만 View단에서 사용할 수 있다. 

 

 

<body>
   <h1> result </h1>
   data1 : ${bean.data1 }
   data2 : ${bean.data2 }
</body>

 

 

 

만약, 빈을 Java가 아니라 xml파일에서 등록한다면??

 

이렇게 id를 등록해주고 저 아이디를 사용하여 @Resource로 가져오면 되겠다.  

 

 

 

 

 

 

 

 

    2.3 @Component 

 

이번에는 컴포넌트를 이용해보자.

 

등록할 빈 클래스에다가 @Component와 @RequestScope를 지정해준다.

컴포넌트 어노테이션을 붙였으니 자바 빈 등록파일에 빈을 따로 등록하지 않아도 DataBean1형의 빈이 등록되었을 것이다. 우리는 @ComponentScan만 잘 해주면 되겠다. 

 

 

 

@Autowired를 이용하여 타입을 통한 자동주입을 해주고 위의 예제들과 유사한 방식으로 사용해줄 수 있다.

 

만약, xml파일에 빈을 등록하는 프로젝트라면~?

 

이렇게 servlet-context.xml에 컴포넌트 스캔을 추가해주면 되겠다.

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

Spring MVC에서의 빈 관리 (ApplicationScope)  (0) 2020.04.28
Spring MVC에서의 빈 관리 (SessionScope)  (0) 2020.04.27
Redirect와 Forward  (0) 2020.04.24
Form 커스텀 태그  (0) 2020.04.24
ViewResolver 에게 전달하기  (0) 2020.04.24

간단하게 코드의 흐름을 생각해보자~

웹 어플리케이션은 브라우저가 서버에 요청을 하게되면 서버가 정보를 분석하고 응답 결과를 생성하여 브라우저로 전달하는 과정을 거친다.
여기에서 서버의 동작은 어떤 분야를 가지고 개발을 하느냐에 따라 달라지게 된다. JSP로 개발을 하면 브라우저의 요청정보를 파일이름으로 판단하고 Servlet으로 개발을 하면 서블릿의 이름으로 판단을 한다.

 

SpringMVC의 경우 요청이 발생하면 요청 주소를 분석하여 그와 매핑되어 있는 메서드를 호출하고 메서드가 반환하는 정보를 토대로 응답결과를 생성하여 클라이언트에게 전달한다.

 

Controller를 통해 요청 주소와 매핑되어 있는 메소드는 반드시 무언가를 반환해야 한다. 우리는 지금까지 문자열, Model, ModelAndView객체를 반환하였다. 

 

 

 

 

1. Redirect

Redirect는 서버가 클라이언트에게 응답결과로 JSP나 HTML같은 데이터가 아니라 요청할 주소를 응답결과로 전달하는 것을 의미한다. 클라이언트는 응답결과로 받은 요청주소를 직접 요청하게 된다. 브라우저가 요청하는 것이므로 주소창의 주소는 변경된다. Redirect는 새로운 요청이 발생하는 것이기 때문에 HttpServletRequest객체는 소멸후 새롭게 생성되며 HttpSession객체는 그대로 유지된다.

 

 

이렇게 반환문에 "redirect:/sub1"; 로 지정하면, 브라우저가 직접 요청하는 것이기 때문에 sub1.jsp가 실행되고 주소창의 주소도 변경된다. 

redirTest를 요청하게 되면 redirTest()메소드가 자동으로 호출되게 되는데 이때 응답결과로 redirTest1.jsp를 반환하는게 아니라, 'sub1을 요청하라'라는 정보를 브라우저에게 전달한다. sub1을 요청하라라는 응답결과를 받은 웹 브라우저는 스스로 sub1을 요청하기 위해서 웹 브라우저의 주소를 sub1으로 변경하게 된다. 이때, 새로운 요청이 발생한것이기 때문에 요청정보를 관리하는 Request객체가 새로 만들어진 것이라고 볼 수 있겠다.

 

 

 

 

2. Forward

Forward는 코드의 흐름을 서버상에서만 이동하는 것이다. 브라우저는 다른 곳으로 흐름이 이동되었다는 것을 알 수 없기 때문에 주소창의 주소는 변경 되지 않는다. HttpServletRequest, HttpSession모두 유지된다.

 

forward를 사용하면 이처럼 주소는 변경되지 않고 client의 요청주소였던 forwardTest에 머물게 되는 것을 알 수 있다.

springMVC에서는 form 커스텀 태그를 지원한다.

 

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

 

View 파일에 다음과 같이 지정을 한다면, form이라는 이름으로 폼 커스텀 태그를 만들 수 있다.

폼 커스텀 태그는 간단하게 코드를 바꿀 수 있을 뿐만 아니라, 자동으로 value값을 주입해 주기 때문에 회원정보 수정이나 글 수정과 같은 페이지에 많이 사용된다.

 

form커스텀 태그의 종류에 대해서는 아래에서 설명하도록 하겠다.

 

 

우선, 빈으로 사용될 VO클래스를 만들어주자. userName, userId, userPassword, userAddr1, userAddr2로 구성되어 있다.

 

 

 

컨트롤러이다. test1이라는 요청값이 들어오면 자동으로 test1메소드가 실행된다. test1메소드는 매개변수로 위에서 만든 UserDataBean을 받고 있다.(@ModelAttribute가 생략되어 있다. 생략되면 Request객체의 이름은 userDataBean이 된다.)

 

 

 

 

실행결과

<form id="userDataBean" action="result" method="post">
	이름 : <input id="userName" name="userName" type="text" value="홍길동"/><br/>
	아이디 : <input id="userId" name="userId" type="text" value="qwer"/><br/>
	비밀번호 : <input id="userPassword" name="userPassword" type="password" value="1234"/><br/>
	주소1 : <textarea id="userAddr1" name="userAddr1">주소1</textarea><br/>
	주소2 : <input id="userAddr2" name="userAddr2" type="hidden" value="주소2"/><br/>
	<button type="submit" value="Submit">확인</button>
</form>

 

 

실행결과와 실행결과창에서 코드보기를 이용해서 결과창 보드를 열어본 결과이다!

여러가지 태그들이 있는데 한개씩 알아보자.

 

1. <form:form>

form태그에서는 Request객체인 UserDataBean을 modelAttribute속성으로 받아준다.(첫 글자는 소문자!) 그리고 form이 동작할 action속성을 선언해준다. 이렇게 실행해주면 form태그 속성은 위와 같이 자동으로 생성되어 지는 것을 볼 수 있다. id가 자동으로 userDataBean으로 설정되고, method도 post로 자동으로 설정되었다.

 

 

2. <form:input>

input는 path를 지정해주면 설정한 문자열은 id와 name속성으로 지정되고 userDataBean안에 들어있는 프로퍼티와 같은 이름을 찾아서 자동으로 value에 주입해주게 된다.

실행 결과 코드를 보면 알 수 있다!!

 

 

3. <form:textarea> / <form:hidden>

form:input과 유사하여 한번에 묶었다. path를 설정해주면 그 문자열은 id와 name속성으로 지정된다. 그리고 그 문자열과 같은 프로퍼티를 찾아서 자동으로 value속성에 주입을 해준다.

 

 

4. <form:button>

form:button은 자동으로 type이 submit인 버튼을 만들어준다. 이 태그에 사용할 수 있는 속성은 disabled가 있다. true로 지정해주면 버튼을 비활성화 시켜준다.

 

 

 

 

이번에는 select, checkbox, radio button에 대해서 알아보자.

 

test3.jsp

<form id="userDataBean2" action="test3" method="get">
	<select id="data1" name="data1">  
		<option value="data1">항목1</option>
		<option value="data2" selected="selected">항목2</option>
		<option value="data3">항목3</option>
	</select>
	<select id="data2" name="data2">
		<option value="data1">data1</option><option value="data2" selected="selected">data2</option><option value="data3">data3</option>
	</select>
	<select id="data2" name="data2">
		<option value="data1">data1</option><option value="data2" selected="selected">data2</option><option value="data3">data3</option>
	</select>
</form>	

 

 

UserDataBean2는 data1과 data2라는 프로퍼티가 있는 빈이다. data1과 data2에는 각각 data2라는 문자열을 삽입해주었다. View에서 13~17줄을 보면 path를 data1으로 지정해준 select가 있다. path가 data1이므로 data1이라는 프로퍼티를 찾아서 알아서 value에 주입해준다. select의 하위 태그중 한개인 option태그를 14~16줄에 사용하였다.

3개의 옵션이 있는데 각각의 value는 data1, data2, data3이다. select태그의 path가 data1이었는데 data1프로퍼티에는 "data2"라는 문자열이 들어있다. select는 option에 value중에서 select의 value(여기서는 "data2"가 되겠다.)와 같은 것을 찾아서 selected옵션을 붙여준다. 즉, value값이 같은 옵션을 맨 처음 선택한 채로 실행된다.

 

계속해서 options태그를 알아보자. test3.jsp의 17~20줄이 되겠다. 

컨트롤러에서 String배열을 만들어서 거기에 data1, data2, data3을 넣었고 그 배열을 "stringList"라는 모델에 담아서(Request객체) View로 넘겨주었다. select속성의 path를 data2로 넣어주고(UserDataBean2빈의 data2라는 이름의 프로퍼티에는 "data2"라는 문자열이 담겨있다.) options태그의 items속성에 그 stringList배열을 담았다.

select태그의 value값(여기서는 "data2"가 되겠다.)과 같은 옵션에 마찬가지로 selected옵션을 붙여주어 맨처음 선택된 채로 실행이 된다.

 

options태그는 String배열 뿐아니라 ArrayList도 지원한다. MyBatis에서 꺼내온 데이터가 ArrayLIst형이기 때문에 매우 편리하게 사용할 수 있을 것이다. test3.jsp 21~23줄이 ArrayList를 사용한 실행코드이다.

 

 

 

그런데..

위의 문제점은, 실행되는 결과의 문자열과 value속성이 무조건 같게 된다는 것이다. value와 별개로 출력되는 select에 문자열을 개발자가 설정할 수도 있을 것이다. 즉, 이번에는 태그사이의 문자를 지정해보도록 하자.

 

 

태그사이의 문자와 value를 구분하기 위해서 key, value라는 이름의 프로퍼티를 가진 빈을 만들었다.

 

 

컨트롤러이다.

KeyValueBean형의 객체3개를 만들어서 각각 key와 value값을 설정해주었다. 그리고 KeyValueBean을 제네릭으로 갖는 ArrayList를 만들어서 위의 객체를 집어 넣어준다. 그리고 keyValueList라는 이름으로 model에 넣어준후 test3.jsp로 반환하였다. 

 

<select id="data1" name="data1">
   <option value="data1">첫번째 항목</option>
   <option value="data2" selected="selected">두번째 항목</option>
   <option value="data3">세번째 항목</option>
</select>

 

 

test3.jsp이다. options의 items를 keyValueList로 설정하였고 itemLable이라는 속성을 key로 받았으며 itemValue라는 속성은 value로 받았다. 이렇게 설정을 해주면 태그사이의 문자열은 key값이 되고 option의 value값은 keyValueList의 value가 된다. select의 path가 data1이므로(userDataBean2의 data1프로퍼티에는 "data2"라는 문자열을 넣어주었었다!!) "data2"라는 문자열과 option의 value가 같으면 selected옵션을 붙여주어 선택된 채로 만들어지게 되겠다.

 

여기서는 data2라는 value의 key값은 "두번째 항목"이라는 문자열 이므로 "두번째 항목"이 선택되어져 있는 select가 만들어지게 되겠다!!

 

 

 

<form:checkbox>, <form:checkboxs>

<form:radiobutton>, <form:radiobuttons>

는 select의 option, options와 유사하므로 생략하도록 하겠다. 각각의 속성이 하는 기능들이 select와 동일하다.

전체적인 MVC동작과정을 다시한번 간단하게 생각해보자.

Controller가 어떤뷰를 사용하겠다는 내용을(ModelAndView객체) DispatcherServlet에게 주면 DispatcherServlet는 클라이언트에게 반환할 정보를 ViewResolver에게 주면 view객체를 만들어서 DSDispatcherServlet에게 다시 전달. 그러면 Model 데이터들을 JSP페이지에 셋팅해서 View를 사용자에 전해준다.

 

Contorller가 DispatcherServlet에게 던져준 ModelAndView객체 안에는 JSP를 구성하기 위해 필요한 데이터와 사용할 JSP가 무엇인지에 대한 정보가 담여져 있다. 정확하게는 Request객체가 들어있다고 할 수 있겠다.

ViewResolver는 컨트롤러에서 받은 View의 이름을 토대로 JSP를 찾아 선택하고 JSP 데이터를 분석해 응답결과를 만들어내는 요소라고 할 수 있겠다!

 

사실, 지금까지 ViewResolver를 계속 사용해왔다. 컨트롤러에서 문자열을 리턴하여 JSP를 찾았는데 내부에서는 ModelAndView객체를 만들어서 그 정보를 가지고 ViewResolver가 받아서 View를 반환해 왔던 것이다.

 

어떤 방법들이 있는지 더 자세하게 알아보도록 하자.

 

 

 

 

1. HttpServletRequest

 

 

HttpServletRequest는 앞에서도 살펴보았던 놈이다. 저번에는 request를 받아서 request.getParameter를 하여 request받은 데이터를 활용만하고 View단으로 넘기지는 않았었다. 이번에는 View로 Request객체를 넘겨보자.

request.setAttribute를 이용하여 data1에는 100이라는 데이터를, data2에는 200이라는 데이터를 담았다.

그리고 return "test1"하여 test1이라는 jsp파일을 View로 사용하고 싶다는 정보를 ViewResolver에게 넘긴것이다.

 

그러면 View단에서는, 

<h2> data1 : ${data1} </h2>
<h2> data2 : ${data2} </h2>

이런식으로 Request데이터를 활용할 수 있겠다.

 

 

 

 

 

2. Model

 

 

이번엔 Model이다. HttpServletRequest와 비슷하다. Model에 담는 데이터를 Request영역에 담아 ViewResolver로 전달하게 된다. Model은 setAttribute가 아니라 addAttribute를 사용한다.

 

<h2> data1 : ${data1} </h2>
<h2> data2 : ${data2} </h2>

View단에서 위와 같이 사용할 수 있다.

 

 

 

 

 

 

3. ModelAndView

 

 

ModelAndView는 Model과 View를 한번에 담을 수 있는 객체이다. 메소드 타입을 String이 아닌 ModelAndView로 만들고, ModelAndView객체를 만들어서 그 객체에 addObject를 이용하여 데이터를 담을 수 있다. (Object이기 때문에 어떠한 형태도 담을수 있겠다.) 또한 setViewName을 이용하여 ModelAndView객체안에 View의 이름까지 담아서ModelAndView객체 자체를 return한다.

 

<h2> data1 : ${data1} </h2>
<h2> data2 : ${data2} </h2>

View단에서는 달라지는 것 없이 위와 같이 Request데이터를 받아올 수 있다.

 

 

 

 

위의 3가지 방식은 개발자에 취향에 따라서 아무거나 써도 된다.

ModelAndView가 깔끔해서 나는 ModelAndView사용하여 프로젝트를 만들었었다.ㅎ

+ Recent posts