Per ardua ad astra !
I'm On My Way
Per ardua ad astra !
전체 방문자
오늘
어제
  • 분류 전체보기 (126)
    • Algorithm (50)
      • 백준 (30)
      • SWEA (3)
      • JUNGOL (3)
      • Programmers (5)
      • LeetCode (2)
    • 안드로이드 개발 (6)
      • Java로 개발 (0)
      • Kotlin으로 개발 (3)
    • Spring (41)
      • Spring기본 (17)
      • JPA기본 (15)
      • JPA활용 SpringBoot 기본 (9)
      • API 개발 기본 (0)
    • 네트워크 (3)
    • 운영체제 (0)
    • Life (3)
      • 책 (0)
      • 자기계발 (1)
      • 일상 (2)
    • 노마드코더 (3)
      • python으로 웹 스크래퍼 만들기 (3)
    • 프로그래밍 언어 (17)
      • Java 기본 (2)
      • 코틀린 기본 (15)

블로그 메뉴

  • 홈
  • 방명록

인기 글

hELLO · Designed By 정상우.
Per ardua ad astra !

I'm On My Way

MVC 1.5: 컨트롤러 구현 없는 경로 매핑(addViewController), ModelAndView, 커맨드 객체의 중첩과 콜렉션 프로퍼티를 뷰 jsp에서 사용하는 방법, Controller에서 모델을 통한 값 전달
Spring/Spring기본

MVC 1.5: 컨트롤러 구현 없는 경로 매핑(addViewController), ModelAndView, 커맨드 객체의 중첩과 콜렉션 프로퍼티를 뷰 jsp에서 사용하는 방법, Controller에서 모델을 통한 값 전달

2021. 1. 26. 15:12

컨트롤러 구현 없는 경로 매핑

 

저번 시간에 회원가입 처리과정을 진행했다. 그 중 step3단계에서는 "회원 가입 완료" 메세지가 등장하고, 홈페이지 메인으로 보낼 수 있도록 설정하고자 했다. 해당 jsp 코드는 애래와 같다.

<p><a href="<c:url value="/main/"/>">[첫 화면 이동]</a></p> 

 

근데 main은 아래의 그림처럼 "환영합니다." 문구와 step1로 가는 경로만 있을 뿐 어떠한 로직이 생성되어 있지 않는 것 같다.  따로 컨트롤러안의 메서드에서 기능구현이나 구체적인 로직이 필요 없는경우 예를들어 이렇게 첫 화면 처럼 특별히 처리할 것이 없는 경우,

우리는 단지 1. URL 매핑과 2. 그에 따른 뷰 값만 전달해 주면 된다. 따로 컨트롤러를 구현하지 않고 경로 매핑할 수 있는 방법은 비교적 간단하다.  

 

 

main 홈페이지

우리는 WebMvcConfigurer 인터페이스의 addViewControllers() 메서드를 사용한다. 

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/main").setViewName("main");
	}

이 메서드를 설정 클래스에 추가하면 된다. addViewController의 값엔 경로매핑을, 그리고 setViewName엔 뷰 이름을 전달하면 된다. main.jsp는 따로 생략하겠다.

 

 

커맨드 객체의 중첩, 콜렉션 프로퍼티

 

저번 시간에 커맨드 객체를 통해 어떻게 요청 파라미터 값을 전달받는지 배웠었었다. 마찬가지로 만약 커맨드 객체의 프로퍼티가 만들어진 다른 객체 이거나, 혹은 콜렉션형태인 ArrayList라던가 List형태일 때 어떻게 jsp에서 이들을 표현해서 커맨드객체를 통해 값을 전달 할 것인지 알아보자.

중첩은 속성이 여러개일 수도 있는 사용자가 만든 객체를 프로퍼티로 사용하는 경우,

콜렉션은 말그대로 프로퍼티가 콜렉션 배열 형태인 경우,로 알아두자.

 

예제) 설문조사

 

Respondent (int age, String location)

AnsweredData(List<String> responses, Respondent res)

 

응답자 정보에 관한 클래스 Respondent가 있다. 답변과 응답자의 정보를 함께 가진 AnsweredData 클래스가 있다. 

클래스엔 모든 속성에 따른 Setter와 Getter가 구현되어 있다. 코드 첨부는 생략한다. 

 

SurveyController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package survey;
 
 
@Controller
@RequestMapping("/survey")
public class SurveyController {
 
    @GetMapping
    public String form(Model model) {
        return "survey/surveyForm";
    }
 
    @PostMapping
    public String submit(@ModelAttribute("ansData") AnsweredData data) {
        return "survey/submitted";
    }
 
}
 
Colored by Color Scripter
cs

Controller는 이와 같이 구성된다. 똑같은 경로 "/survey"를 이용하더라고, 그 요청방식이 Get방식이냐 Post방식이냐에 따라 페이지 구성이 달라지므로, 처음에 홈페이지 URL을 치고 입장했을 땐 surveyForm이 등장하고, 폼 입력, 제출후에는 submitted 홈페이지가 등장한다.  

submit 메소드에서 쓰인 커맨드 객체는 AnsweredData이며 커맨드 명을 ansData로 설정했다. 자 이제 jsp에서 커맨드 객체에게 어떻게 값을 전달했는지 보자. 

 

 

SurveyForm.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<%@ page contentType="text/html; charset=utf-8" %>
<!DOCTYPE html>
<html>
<head>
<title>설문조사</title>
</head>
<body>
    <h2>설문조사</h2>
    <form method="post">
        <p>
            1. 당신의 역할은?<br/>
            <label><input type="radio" name="responses[0]" value="서버">서버개발자</label>
            <label><input type="radio" name="responses[0]" value="프론트">프론트개발자</label>
            <label><input type="radio" name="responses[0]" value="풀스택">풀스택개발자</label>
        </p>
        <p>
            2. 가장 많이 사용하는 개발도구는?<br/>
            <label><input type="radio" name="responses[1]" value="Eclipse">Eclipse</label>
            <label><input type="radio" name="responses[1]" value="Intellij">Intellij</label>
            <label><input type="radio" name="responses[1]" value="Sublime">Sublime</label>
        </p>
        <p>
            3. 하고 싶은 말<br/>
            <input type="text" name="responses[2]">
        </p>
        <p>
            <label>응답자 위치: <br>
            <input type="text" name="res.location">
            </label>
        </p>
        <p>
            <label>응답자 나이: <br>
            <input type="text" name="res.age">
            </label>
        </p>
        <input type="submit" value="전송">
    </form>
</body>
</html>
Colored by Color Scripter
cs

9행: path를 설정안 했으면 자기 자신의 경로 그대로 다시 전달한다. 여기서는 method = "post" 방식으로 전달했다. 

12~14행: 설문조사를 위한 radio 타입 3개 생성. name = "response[0]"이다.

               response는 AnswerdData의 첫번째 프로퍼티이며 콜렉션 어레이 형식이 이었다. 표기 방법을 기억하자.

18~20행: 위와 마찬가지다.  name="response[1]"

28행, 33행: 응답자의 정보도 AnswerData에 담기위해 Respondent 타입의 프로퍼티가 존재한다고 했다. 

                name="res.location", name="res.age"

 

정리

요청 파라미터의 이름이

     "프로퍼티이름[인덱스]" 형식: List타입 프로퍼티의 값 목록으로 처리

     "프로퍼티이름. 프로퍼티이름" 형식: 중첩 프로퍼티 값으로 처리

 

 

컨트롤러에서 Model을 통해 뷰에 데이터 전달

 

우리는 저번시간에 뷰 jsp에서 커맨드 객체를 사용할 수 있도록 하는 방법과, @ModelAttribute 어노테이션으로 커맨드 객체의 속성이름을 지정해 주는방법을 배웠었다. 그렇다면 만약 커맨드 객체가 없을 때는 컨트롤러에서 어떻게 뷰에 데이터를 전달하는지 알아보자. 처음 딱 설문조사 폼에 들어올때는 당연히 커맨드 객체가 없다. 고로 Model을 활용해야한다.

 

예제 통해 알기

만약 질문지도 일일히 jsp에서 하드코딩하기 보다, Controller에서 질문지 값을 전달할 수 있으면 더 좋겠다는 생각을 하자. 이게 가능하다면 Controller에서 질문지 값만 바꿔주면 되기 때문이다. 

 

Question (String title, List<String> options)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package survey;
 
import java.util.Collections;
import java.util.List;
 
public class Question {
    // 질문
    // 제목, 선택지
    private String title;
    private List<String> options;
 
    public Question(String title, List<String> options) {
        this.title = title;
        this.options = options;
    }
 
    public Question(String title) {
        this(title, Collections.emptyList());
    }
 
    public String getTitle() {
        return title;
    }
 
    public List<String> getOptions() {
        return options;
    }
 
    public boolean isChoice() {
        return options != null && !options.isEmpty();
    }
 
}
 
Colored by Color Scripter
cs

질문지를 담당하는 객체이다. 

12행: 필드 2개를 모두 필요로한 생성자(객관식용)

17행: 필드 1개(String title)를 필요로한 생성자(주관식용), options 속성값에는 emptiyList가 들어감

나머지행: Getter와 Setter들 + isChoice라는 메서드 => 질문지가 비었는지 안비었는지 확인 = 주관식인지 객관식인지

 

 

SurveyController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package survey;
 
import java.util.Arrays;
import java.util.List;
 
@Controller
@RequestMapping("/survey")
public class SurveyController {
 
//    @GetMapping
//    public ModelAndView form() {
//        List<Question> questions = createQuestions();
//        ModelAndView mav = new ModelAndView();
//        mav.addObject("questions", questions);
//        mav.setViewName("survey/surveyForm");
//        return mav;
//    }
 
    @GetMapping
    public String form(Model model) {
        List<Question> questions = createQuestions();
        model.addAttribute("questions", questions);
        return "survey/surveyForm";
    }
             
    private List<Question> createQuestions() {
        Question q1 = new Question("당신의 역할은 무엇입니까?", Arrays.asList("서버", "프론트", "풀스택"));
        Question q2 = new Question("많이 사용하는 개발도구는 무엇입니까?", Arrays.asList("이클립스", "인텔리J", "서브라임"));
        Question q3 = new Question("하고 싶은 말을 적어주세요.");
        return Arrays.asList(q1, q2, q3);
    }
 
    @PostMapping
    public String submit(@ModelAttribute("ansData") AnsweredData data) {
        return "survey/submitted";
    }
 
}
 
Colored by Color Scripter
cs

 

26행: 질문지 생성 메소드

20행: 파라미터에 모델 삽입 

22행: 생성한 질문지들을 addAttribute() 메서드를 통해 뷰에 값들을 모두 전달.  

 

10~17행: 주석으로 처리한 이 메소드도 아래 19~24행 메소드와 같은 기능이다. 단지 Model 파라미터를 제거하고 뷰 주소를 리턴하는 방법을 합치는 것이다. ModelAndView 라는 객체를 생성하고 addObject()를 통해 뷰에 데이터를 전달하고, setViewName() 메서드를 활용해서 뷰 경로를 지정한다. 마지막으로 ModelAndView 객체를 리턴한다. 

 

surveyForm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>설문조사</title>
</head>
<body>
    <h2>설문조사</h2>
    <form method="post">
    <c:forEach var="q" items="${questions}" varStatus="status">
    <p>
        ${status.index + 1}. ${q.title}<br/>
        <c:if test="${q.choice}">
            <c:forEach var="option" items="${q.options}">
            <label><input type="radio" 
                           name="responses[${status.index}]" value="${option}">
                ${option}</label>
            </c:forEach>
        </c:if>
        <c:if test="${! q.choice }">
        <input type="text" name="responses[${status.index}]">
        </c:if>
    </p>
    </c:forEach>
 
    <p>
        <label>응답자 위치:<br>
        <input type="text" name="res.location">
        </label>
    </p>
    <p>
        <label>응답자 나이:<br>
        <input type="text" name="res.age">
        </label>
    </p>
    <input type="submit" value="전송">
    </form>
</body>
</html>
 
Colored by Color Scripter
cs

jsp구현에 있어서 우리는 커스텀 태그의 일종인 jstl을 사용할 것이고, 그 중에서 Core태그(taglib prefix:"c"를 사용한다.

<c:forEach>

  • items = "${리스트이름}"
  • var = "collecion에서 하나씩 가져올 때 담을 단일 객체 이름"
  • varStatus="일련의 송석들을 정의한 객체" => 주로 인덱스넘버용으로 사용됨 

<c:if>

  • test = "${조건(true or false)}"  => questions에는 isChoice()라는 메소드가 있음. is빼고 소문자로 바꾸면 속성이름으로 사용가능 ex) 14, 21행참고
  • var = "조건을 검사하고 리턴되는 boolean값 저장하는 이름" => 생략가능
  • scop = "var의 속성값이 유효한 범위 지정" => 생략가능 

11행: 우리가 Controller에서 모델에 전달한 "quesions" 속성명을 가지고 값들에 접근하는 모습이다. 

 

 

방법 정리

  1. Model을 요청매핑 메소드의 파라미터에 넣는다. 
  2. Model의 addAttribute("뷰에서 사용할 속성이름", 전달할 값)  메소드를 활용한다.
  3. 뷰 JSP에서 ${"속성이름"} 이런식으로 속성값에 접근한다.

 

+ 추가 공부 

@ModelAttribute를 메소드에 명시해서 사용하는 경우. 

해당 메소드는 다른 어떤 메소드가 호출되던간에 같이 호출되어 항상 사용이 가능함.

 

ex)

@ModelAttribute("serverTime")

public String getServerTime(Locale locale){

    Date date = new Date();

    DateFormat dateFormat = DateFormat.getDateTime(DateFormat.LONG,..)

    

    return dateFormat.format(date);

}

 

 

 

출처: 초보 웹 개발자를 위한 스프링5 프로그래밍 입문

 

    'Spring/Spring기본' 카테고리의 다른 글
    • MVC 3: 세션, 쿠키
    • 스프링 톰캣 서버 실행시 등장하는 오류, MySQL을 JDBC를 통한 연동시 오류
    • MVC 1: 요청 매핑 어노테이션, 리다이렉트, 요청 파라미터 접근, 커맨드 객체, 폼태그
    • Tansaction 처리
    Per ardua ad astra !
    Per ardua ad astra !
    개발자 지망생이며 열심히 공부하고 기억하기 위한 블로그입니다.

    티스토리툴바