IT 강의 정리/윤재성의 스프링 MVC5

[섹션1][Spring MVC의 다양한 기능들] 10~19강

Nellie Kim 2022. 10. 24. 19:33
728x90

10. URL Mapping

Servlet / JSP URL 주소

- URL주소 : 사용자가 서버에 접속해서 서비스를 받기 위해 입력하는 주소

- URL주소 구성 :  프로토콜://도메인주소(IP)/포트번호/경로1/경로2/경로3/...

- 프로토콜 : 서버와 클라이언트간의 통신을 위한 약속 (생략시 http)

- 도메인주소(IP주소) : IP주소는 같은 네트워크 망에서 컴퓨터를 구분하기 위해 제공되는 숫자로 구성된 고유 주소.

- 포트번호 : 1~65535 번까지 구성된 숫자. 컴퓨터 내에서 프로그램을 구분하기 위해 사용한다.(생략시 80)

- 경로1/경로2/경로3..: 이 부분은 서버 혹은 개발 방식이나 분야에 따라 다르게 해석된다. Servlet/JSP에서 첫번째 경로는 Context Path라고 부른다. 하나의 서버에서 각 웹 애플리케이션을 구분하기 위해 저장되는 이름이며, 폴더이름이 Context Path가 된다. 그 이후 경로는 하위 경로가 된다.

 

아파치톰캣기반의 웹어플리케이션은 url주소창에 localhost:8080을 치면 기본적으로 webapps의 ROOT폴더로 들어가서 해당파일을 찾게되지만, url주소창에 localhost:8080/aaaa 라고 치면 ROOT말고 aaaa로 찾아 들어간다.

이때 aaaa폴더의 경로를 Context Path라고 한다. 아래 각 폴더 하나하나를 어플리케이션 하나의 단위라고 생각하면 된다.

우리가 지금까지 작업했던 프로젝트파일들이 실제 실행될 수 있는 형태로 변환이 되어 아래 경로에 저장이 된다.

workspace > .metadata > .plugins > org.eclipse.wst.server.core > tmp0 > wtpwebapps 

여기 안의 폴더들도 마찬가지로 ContextPath가 된다. 우리가 다룰 URLMapping은 ContextPath이후의 주소를 세팅한다.

Spring MVC에서는 Context Path 다음에 나오는 주소는 실제 물리적인 경로와 다르게 지정할 수 있다.

하위경로는 이렇게 / 단위로 써주면 된다.

경로가 많다면 아래와 같이 통합할 수 있다.

11. 요청방식

요청방식에 따라 메서드를 정의할 수 있다. GET, POST, PUT, DELETE, PATCH 등이 있는데,

여기서는 GET, POST만 실습해보자.

 

@RequestMapping

아래와 같은 상황을 보자. 컨트롤러에서 test1은 GET방식, test2는 POST방식으로 요청을 했다. 

실행해 보면, test1 get을 클릭했을 때 잘 실행이 되지만, test1 post버튼을 눌렀을때 405에러가 난다. 반대로,

test2 get을 클릭했을 때 405에러가 나고, test2 post버튼을 눌렀을때 정상 실행이 된다.

 

@GetMapping, @PostMapping

@RequestMapping대신 요청별로 @GetMapping, @PostMapping 어노테이션을 사용할 수도 있다. 

그러나 @GetMapping, @PostMapping 어노테이션은 요청방식을 동시에 지정할 수 없어서 , 요청방식을 동시에 지정하고 싶을 때는 @RequestMapping를 사용하도록 하자.

12. 파라미터 추출하기

파라미터를 메서드의 매개변수로 주입을 받아보자. 3가지 방법이 있다.

1 . HttpServletRequest / WebServletRequest 사용하기

Spring MVC는 필요한 객체나 데이터는 주입을 받아 사용한다.

Servlet / JSP에서 파라미터 데이터를 추출할 때 HttpServletRequest객체를 통하게 되는데, Spring MVC에서 이 객체를 주입받아 사용할 수 있다.

파라미터  추출 뿐 아니라 HttpServletRequest객체가 필요할 경우 사용하면 된다.

 

WebRequest는 HttpServletRequest를 확장한 클래스이다. 기능이 좀 더 많다. 사용방법은 동일하다.

 

2. @PathVariable 사용하기

 

PathVariable은 아래와 같이 경로처럼 값을 넣어준다. WebRequest와 비교.

 

3. @RequestParam 사용하기

- @RequestParam은 파라미터 데이터를 직접 주입 받을 수 있다.

- 지정된 변수의 이름과 파라미터의 이름이 같을 경우 값을 주입 받는다.

- 가능한 경우 형변환도 처리해준다.

- value : 파라미터의 이름과 변수의 이름이 다를 경우 파라미터의 이름을 지정한다.

- required : false를 설정하면 지정된 이름의 파라미터가 없을 경우 null이 주입된다.

index.jsp
TestController.java
실행결과

13. 객체로 파라미터 주입받기

지금까지 파라미터를 메서드의 매개변수로 주입을 받았다. 그런데 만약, 파라미터 데이터가 50개가 날라온다면, 50개의 변수를 일일이 정의해야 한다. 그럴 때는 너무 불편해지기 때문에 객체로 주입받아야한다.

이번에는 객체로 파라미터를 주입받아보자.

1. Map으로 주입받기

클라이언트가 전달하는 모든 파라미터 데이터를 한번에 Map으로 받을 수 있다.

단, 동일명으로 전달되는 2개이상의 파라미터는 하나만 담기게 된다.

동일명으로 전달되는 파라미터가 2개 이상이라면 List로 주입받아야 한다.

Map으로 주입받을때는 동일명(data3)으로 전달되는 파라미터는 1개만 담기게 된다.

실행결과에 300, 400이 아닌 300만 출력되었다.

index.jsp
TestController.java
실행결과

파라미터 300, 400 모두 받아오고 싶으면, List 매개변수도 추가해 줘야 한다. 아래와 같이 잘 출력이 된다.

주의할 점은, 들어오는 데이터가 모두 숫자라고 하더라도 형변환 되지 않기때문에 컨트롤러에서 데이터를 받아올 때는 무조건 String으로 받아와야 한다.

2. @ModelAttribute로 객체 주입받기

이제 진짜 객체로 주입 받아보자.

@ModelAttribute 어노테이션을 사용하면 파라미터를 객체로 주입받을 수 있다.

전달되는 파라미터의 이름과 동일한 프로퍼티에 자동으로 주입된다.

이 어노테이션은 생략이 가능하며, 이러한 객체를 커맨드객체(Command Object)라고 부른다.

 

먼저 index.jsp에 동일하게 데이터를 넣어준다.

객체로 받을 때는 형변환도 자동으로 이루어지기 때문에, 타입을 원하는 타입으로 지정해줘도 된다. 

beans 패키지 생성>  DataBean클래스생성. 데이터명과 동일하게 필드에 작성하고 게터세터메소드도 넣어주기.

TestController클래스에 아래처럼 DataBean클래스를 매개변수로 받아와 출력해준다.

이렇게 객체를 주입받으니 데이터를 개별로 받아오지 않아도 되니 편하다. @ModelAttribute는 생략 가능하다.

14. ViewResolver

컨트롤러에서 전달받은 View의 이름을 토대로 jsp를 찾아 선택하고 jsp데이터를 분석해 응답결과를 만들어 전달한다.

여기서는 ViewResolver가 사용할 View의 이름을 지정하는 방법jsp를 통해 응답결과를 만들 때 필요한 데이터를 전달하는 방법을 배워보자.

Controller에서 View를 지정할 때 ViewResolver가 사용할 데이터를 Request영역에 저장할 수 있는데, 3가지 방법이 있다. HttpServletRequest, Model, ModelAndView 중 1가지를 사용할 수 있다.

1.  HttpServletRequest 사용

2.  Model 사용

3.  ModelAndView 사용

셋 중 아무거나 편한 것을 사용해도 되지만, 선생님은 Model을 많이 쓰신다고 한다.

 

요약
ViewResolver에 의해 JSP가 실행되고 응답결과가 만들어진다.
Controller에서 View를 지정할 때 ViewResolver가 사용할 데이터를 Request영역에 저장할 수 있다.

 

요약
데이터의 흐름은 클라이언트브라우저 → 컨트롤러 → JSP로 전달된다.
A. 클라이언트브라우저 → 컨트롤러로 데이터를 보내는 방법 (파라미터 추출하는 방법) 4가지
1. HttpServletRequest / WebServletRequest
2. @PathVariable 
3. @RequestParam 
4. @ModelAttribute
3,4번을 제일 많이 사용한다.

B. 컨트롤러 → JSP로 데이터를 보내는 방법 3가지 (사용하는 메소드도 각각 다름)
1. HttpServletRequest (request.setAttribute())
2. ModelAndView (mv.addObject())
3. Model (model.addAttribute())
포함관계 : HttpServletRequest ⊂ Model ⊂ ModelAndView

15. 커맨드객체 이용하기

클라이언트가 전달해 주는 파라미터 데이터를 주입받기 위해 사용하는 객체

커맨드 객체는 HttpServletRequest 객체에 자동으로 담기고 jsp로 전달된다. 즉, 우리가 bean을 request에 담는 행위를 하지 않아도 된다는 것이다.  @ModelAttribute는 생략을 해도 된다.

이때, request영역에 어떤 이름으로 저장되는지 알아야, 우리가 가져다 쓸 수가 있다.

HttpServletRequest객체에 저장되는 이름은 클래스의 이름으로 결정된다.

HttpServletRequest에 저장되는 이름을 지정하고 싶다면 ModelAttribute어노테이션에 지정하면 된다.

요약 ) 커맨드객체는 자동으로 HttpServletRequest객체에 담기게 된다.

16. Form 커스텀 태그

스프링에서는 <form:태그명> 형태로 되어있는 커스텀 태그를 제공하고 있다.

Form커스텀 태그를 활용하면 Model객체에 들어있는 값을 form요소에 주입시킬 수 있다.

회원 정보 수정 등 정보 수정페이지를 구성할 때, 사용자가 전에 입력했던 내용을 보여주는 등 요긴하게 사용할 수 있다.

 

먼저, 스프링의 form커스텀태그를 이용하지 않고 실행해보자.

1) test1.jsp파일에서 회원정보 입력화면을 먼저 만들고 실행시켜보자. 아래와 같이 출력된다.

이 화면이 정보수정페이지라고 하면, 화면에 사용자가 전에 입력했던 정보들이 나와야 한다. 그 정보를 데이터베이스에서 읽어와서 JSP에 전달해주면 JSP가 받아서 사용하게 된다. 

2) UserDataBean클래스만들어서 정보를 담아놓을 빈을 만들기. 

test1.jsp에서 지정한 데이터와 동일한 데이터를 만들고, 게터세터메소드 만들기.

3) TestController클래스에서 커맨드 객체를 이용해서 작업하기.

4) 다시 test1.jsp파일에 가서 value값을 지정해준다.

5) 실행해보면 입력했던 값이 잘 나타난다.

이제, 스프링MVC에서 제공하는 form커스텀태그를 이용해보자. 4)번과정을 더 간편하게 할 수 있다.

1~3) 동일

4-1) test2.jsp 파일에서 커스텀태그 URI설정을 해줘야 한다.

4-2) 아래와 같이 form태그를 사용해서 type, name, value 다 필요없이 path만 지정해주기

보통 비밀번호는 보안상의 이유로 노출되지 않는데, 보여주고 싶다고 하면 jsp의 path 옆에 showpassword="true"라고 넣기

비교하기

 

요약 ) <form:> 커스텀 태그를 이용하면 Model 객체와 유기적으로 동작할 수 있다.

17. Form 요소1

<form:>태그를 활용한 기본 입력 요소를 구성해보자.

request영역에 담겨져 넘어오는 다양한 값들을 input등 태그에 바인딩시켜서 사용자 입력폼을 만들 수 있고,

주로 정보 수정 페이지를 구성할 때 사용한다.

아래 주소에 들어가 보면 해당 태그에 대해 자세히 설명되어있다.

 

1. <form:form> 태그

- <form> 태그를 생성한다.

- modelAttribute : form태그 내의 입력 요소들에 적용될 value값을 가진 객체이름. 이 속성의 값이 id속성으로 설정된다.

생략 시 command라는 문자열이 id로 설정된다.

- action : 요청할 주소를 설정한다. 생략 시 현재 페이지가 설정된다.

- method : 요청 방식을 설정한다. 생략 시 post로 설정된다.

 

아래처럼 test1.jsp에 기본 form태그만 넣고 실행하면, 페이지소스보기에서 아래처럼 기본값이 설정된다.

이번에는 ModelAttribute로 DataBean을 받아오자. dataBean이란 이름으로 request에 저장된다. jsp파일에 빈 이름을 세팅해주고 실행하면 페이지소스가 아래와 같이 나온다. id값이 dataBean으로 변경되었다.

modelAttribute, action, method 모두 아래와 같이 지정하면, 페이지 소스에 그대로 반영이 된다.

2. <form:button> 태그

- Submit 버튼을 생성한다.

- disabled : true를 세팅해주면 버튼을 누를 수 없도록 비활성화 된다.

 

3. <form:hidden> 태그

- Hidden 타입의 input 태그를 생성한다.

- path : 설정한 문자열은 id와 name 속성으로 지정되며, model의 값을 추출해 value속성에 주입한다.

 

4. <form:input> 태그

- text 타입의 input 태그를 생성한다.

- path : 설정한 문자열은 id와 name 속성으로 지정되며, model의 값을 추출해 value속성에 주입한다.

 

5. <form:password> 태그

- password 타입의 input 태그를 생성한다.

- path : 설정한 문자열은 id와 name 속성으로 지정되며, model의 값을 추출해 value속성에 주입한다.

- showPassword : 세팅될 값의 이름을 지정하더라도 값이 세팅되지 않는데, true를 넣어주면 값이 세팅된다.

 

6. <form:textarea> 태그

- textarea 타입의 input 태그를 생성한다.

- path : 설정한 문자열은 id와 name 속성으로 지정되며, model의 값을 추출해 value속성에 주입한다.

 

18. Form 요소2

1. <form:select> 태그

- select 태그를 생성한다. select는 그 안에 들어있는 항목을 구성하기 위해 option태그를 이용하게 된다.

- path : 설정한 문자열은 id와 name속성으로 지정되며 model의 값을 추출해 값과 동일한 value속성의 option태그를 선택한다.

2. <form:option>, <form:options> 태그

- select태그의 option태그를 생성한다.

- items : option 태그들을 생성할 때 필요한 데이터가 담긴 list나 배열

 

아래 코드를 보면, TestController에서 data2를 세팅하고, test1.jsp에서 option태그를 이렇게 달아주면, value값과 일치하는 옵션태그가 선택된 상태로 브라우저에 태그가 나타나게 된다.

아래처럼 배열로도 가능하다.

request에 담아서 jsp에 넘겨야하기 때문에 Model객체를 먼저 주입을 받고, 배열 만든 후에(나중에는 MyBatis를 이용해서 데이터베이스의 항목을 직접 가져다 쓰면 된다), model.addAttribute로 배열을 저장한다.

jsp에서 requestScope.data_list1 로 배열을 받아온다. 

페이지소스보기를 해보면 value속성의 값과 문자열이 'data1','data2' 이런식으로 동일하게 들어가있다.

ArrayList로 세팅가능하다. 나머지 코드 및 결과는 동일하다.

만약에 value속성의 값과 문자열이 다르게 들어가게 하고싶다면,

KeyValueBean클래스 새로 만들어서 key, value속성 넣어주고, 컨트롤러에서 객체 생성하여 데이터 넣어주고, jsp파일에서 태그사이에 문자열(화면에보여질문자열)은 itemLabel="key", value속성은 itemValue="value" 라고 추가 작성해주기

페이지소스를 보니, Label값은 key값으로 '항목'이 잘 들어가있고, value값은 value값 설정한대로 'data'값이 잘 들어갔다.

 

3. <form:checkbox>, <form:checkboxs> 태그

- checkbox 태그를 생성한다.

- items : checkbox들을 생성하기 위해 필요한 데이터가 담긴 list나 배열

 

DataBean에 a5~a8배열객체 만들어주고, 컨트롤러에 객체에 모두 data1, data3 리스트 넣어주고, jsp에서 a5만 호출하게되면, 브라우저에는 data1, data3만 체크가 되어 나타난다. 객체에 data1, data3밖에 없으니까.

select와 마찬가지로 checkbox도 배열로 지정해줄 수 있다. value와 문자열이 동일하게 세팅된다.

 

4. <form:radiobutton>, <form:radiobuttons> 태그

- radiobutton 을 생성한다.

- items : radiobutton들을 생성하기 위해 필요한 데이터가 담긴 list나 배열

 

라디오버튼도 체크박스와 형태는 동일하다.

 

19. Redirect와 Forward

코드의 흐름

웹 애플리케이션은 브라우저가 서버에 요청을 하면 요청 정보를 분석하고 응답결과를 생성하여 브라우저로 전달한다.

여기에서 서버의 동작은 어떤 분야를 가지고 개발을 하느냐에 따라 달라지게 된다.

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

 

메서드의 리턴

Controller를 통해 요청주소와 매핑되어 있는 메서드는 반드시 무언가를 반환해야 한다.

우리는 지금까지 문자열, Model, ModelAndView를 반환했다.

이들은 모두 브라우저에게 전달할 응답결과를 생성하기 위한 JSP를 지정하는 부분이다.

이 밖에도 다양한 정보를 반환할 수 있으며 이를 토대로 동작을 제어할 수 있다.

 

Redirect

Redirect는 서버가 클라이언트에게 요청할 주소를 응답결과로 전달하는 것이다.

클라이언트는 응답결과로 받은 요청주소를 직접 요청하게 된다.

브라우저가 요청하는 것이므로 주소창의 주소는 변경된다.

Redirect는 새로운 요청이 발생하는 것이므로 HttpServletRequest객체는 소멸 후 새롭게 생성되며 HttpSession객체는 그대로 유지된다.

 

forward

코드의 흐름을 서버상에서만 이동하는 것이다.

브라우저는 다른 곳으로 흐름이 이동되었다는 것을 알 수 없기 때문에 주소창의 주소는 변경되지 않는다.

HttpServlet, HttpSession 모두 유지된다.

 

 

요약: Redirect는 클라이언트에게 새로운 페이지요청을 응답결과로 전달, Forward는 서버상에서 코드의 흐름이 이동함.

 

 

출처 : [인프런] 윤재성의 만들면서 배우는 Spring MVC 5