Web/Spring

[Spring] Ch02.Spring MVC (19) 회원가입 화면 작성하기, (20)@GetMapping, @PostMapping (22) redirect와 forwarding

OptimizerStart 2025. 6. 8. 22:26

Spring MVC

 

 

회원가입 화면 작성하기

 

 

url 경로에서 resources 없애는 법

  • location에서 /로 바꾸면 됨.

servlet-context.xml (웹 관련 설정 파일)

servlet-context.xml

root-context.xml (non-web 설정 파일)

 

<form>

method="GET/POST"

  • default = GET
    • 쿼리 스트링으로 사용자 입력값 전달됨

action="전송할 url"

  • default = 자기 자신

🟡 TIP 개발자 도구 Source보기로 변경되었는지 확인

 

쿼리 스트링의 이름(name)에 여러 값이 넘어오는 경우

?sns=facebook&sns=kakaotalk&sns=instagram

String[] 배열로 요청 결과를 받음

String[] snsArr = request.getParameterValues("sns"); 

 

EL ${paramValues.sns[인덱스]}

param 내장 객체를 활용한 요청 값 읽기

 

URL 인코딩/디코딩 = 퍼센트 인코딩 ⭕ 면접 base64 비교 . 암기

Non ASCII 를 ASCII (문자)코드(16진수)로 문자열로 변환

문자코드(숫자)를 문자열로 변환

  • 이유 : 서버의 OS, 인코딩 종류를 모르기 때문에 URL 요청 시 ASCII(공통 문자표) 이용
  • 원리 : 한글 1글자 = 3Bytes

특징

  • 메서드 유형(GET,POST)에 상관없이 브라우저가 URL 인코딩이 되어 서버에 전송
    • 서버가 받은 데이터를 서버에서 URL 디코딩 해야함. (필수) → 귀찮음 한글 Encoding Filter
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");

 

/WEB-INF/web.xml 한글 필터링

CharacterEncodingFilter

  • DispatcherServlet으로 보내기 전 인코딩(한글) 전처리 코드.
  • maven 의존성 파일 .m2 에 저장

 

요청과 응답에 대한 한글 처리 전처리 코드

base64  ⭕면접 

  • cf. Base64 이미지 전송을 위해 바이너리 데이터를 텍스트 데이터로 변환
    • 6bit 씩 1글자

URL 한글 포함된 경우 URL 인코딩된 값이 전송이 됨

  • 실제 URL 창에는 한글이 보여도 실제는 %들어간 ASCII문자로 변환되어 전송

URL 한글표시

// 실제 전달되는 값
http://localhost:8080/ch2/registerForm.html?id=asdf&pwd=1234&name=%EB%B0%95%EC%A7%80%ED%98%95&email=qwer%40gmail.com&birth=2000%2F01%2F01

 

🟡 TIP URL 한글자 빼고 복사 시 한글이 복사됨

  • 문서 작성
ocalhost:8080/ch2/registerForm.html?id=asdf&pwd=1234&name=박지형&email=qwer%40gmail.com&birth=2000%2F01%2F01

 

 

필수 값들 전송 체크

  • ex. id, pwd

방법

  • JS 체크 - form 태그 이벤트 등록 onsubmit (전송할 때 지정한 함수 호출)
    function () { // 익명 함수
    	return formCheck(this); // 이 부분만 이벤트 등록 때 사용 
    	}
    
  • onsubmit =”return formCheck(this)”
  • 서버 체크

autofocus

페이지 첫 로딩 후 커서 껌뻑껌뻑

 

Template Literal

  • JS. 브라우저에서 돌아감.
  • `` 백틱으로 감쌈
  • 해당 시점의 JS 변수의 값을 대신 삽입

cf. EL 서버에서 돌아감

서버에서 먼저 돌아가고 그 결과값이 브라우저에서 수행

  • 서버가 ${msg}를 EL로 해석함. 서버가 해석하는 단계에서 msg는 빈 문자열로 해석하여 브라우저에게 빈 문자열로 전달됨. → 3 길이 이하일 때 아무것도 출력이 안되는 이유
  • EL은 백틱이 필요없음
  • ${'${msg}'} EL이 ‘’ 문자열 내부 해석${msg}${메세지 내용} 만 남음
    • EL 파서는 첫 ${를 만나면 가장 먼저 나오는 } 까지를 하나의 표현식으로 인식

jsp 내의 js 코드 template literal과 el 해석 시점 차이

 

 

context-root

  • <c: url value=”url”/>
  • context-root를 하드코딩 안해도 바뀌는 값을 자동 적용

[왼쪽} c:url 태그로 자동 추가된 context-root, [오른쪽] 자동 추가된 context-root

<c: url> 기능 -2

  1. context-root 자동 추가
  2. session id 자동 추가

 

 

@GetMapping, @PostMapping

GET 회원 가입 위험성

  • ID,PW 누출
  • 회원가입 자동화

@RequestMapping

  • 작성 안한 경우, GET, POST 둘다 허용
  • 간략화 한 애너테이션 @GetMapping, @PostMapping
  • url 중복 불가.

특징

  • URL 패턴 사용 가능 → 우선 순위 존재
  • ? 물음표 개수만큼의 문자만 대체할 때 사용
    • ?? 문자 2개만 매칭
    • - . 도 하나의 문자 취급
    @RequestMapping("/login/??")
    /login/ab // 매칭
    /login/xy // 매칭
    /login/a //  X 총 2글자 필요
    /login/abc // X 3글자라서 2글자만 허용
    
  • * 0글자 이상 대체
    • / 새로운 세그먼트 오기 전까지 0개 이상 글자 와도 됨
    @RequestMapping("/login/*")
    /login / // 매칭
    /login/a // 매칭
    /login/basdf // 매칭
    /login/.do // 3글자 매칭
    /login/main/sub // X login이후 첫번째 /까지만 인정 
    
  • ** 더블스타 (ANT) 0개 이상의 폴더 (또는 / 경로 세그먼트)
    • 하위에 어떤 경로가 오든 모두 매칭
    @RequestMapping("/login/**/tmp.do")
    /login/main/sub/tmp.do // 매칭 
    
    URL 패턴 특징
    서블릿 @WebServlet * 여러 글자
    ** 하위경로 포함    
    Spring @RequestMapping ? 한글자
    우선 순위 의미
    1 exact mapping 정확히 일치  
    2 path mapping 경로 매핑  
    3 extenstion mapping 확장자 매핑  
    4   404 not found  

@GetMapping , @PostMapping 특징

  1. method 다르면 URL 중복 가능
  2. URL의 공통 부분은 클래스에 붙이는 @RequestMapping 에 정의 가능.
    • 다른 부분 URL 만 메서드의 @Get/PostMapping으로 붙이기
    • 클래스안에 있는 메서드 앞에 공통 URL이 붙음
    • 목적 : 모듈 별로 메서드를 넣음 ( 1 클래스에 모든 메서드 넣기 X)

 

@PostMapping

간략화 표현 @RequestMapping(value="/register/save", method=RequestMethod.POST)

특징

  • Spring 4.3 버전 부터 추가됨

예시

  • @PostMapping 설정된 메서드는 쿼리스트링 제공 시 허용되지 않는 메서드 에러 발생

허용되지 않는 메서드 - POST 방식만 허용하기 때문.

 

Spring Framework 버전 확인 (5.3.15) maven dependencies

  • 버전 변경 pom.xml <org.springframework-version> 태그 내용 수정 후 maven> project update

Maven Dependencies 폴더 - 사용중인 spring framework 버전 확인

 

메서드가 view만 보여주는 기능만 있는 경우

view -controller로 변경 - @Controller 코드 제거

  • GET 요청만 허용. POST
  • POST 요청 테스트 - PostMan

servlet-context.xml (웹 관련 설정)에 view-controller 설정 추가

	<!-- View Controller 주소를 jsp view와 연결 -->
	<view-controller path="/register/add" view-name="registerForm"/>

 

 

servlet.xml

  • xmlns :  xml에서 쓰는 namespace
    • 각 스키마에서 정의한 태그를 사용하기 위해 정의해 놓은 것.
    • 각 namespace 마다 접두사( xsi beans context 등)을 정의해야함
  • 접두사 종류
    • mvc : mvc 스키마에 정의된 태그는 mvc 태그 붙여야함. 생략가능 .
    • <mvc:resources>
<beans:beans xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
		--
			<mvc:view-controller path="/register/add" view-name="registerForm"/>
		--

 

 

메세지 전달 방법 -2

  1. URL 재작성 (rewriting) 
return "redirect:/register/add?msg=" + msg; // URL 재작성 (rewriting)

URLEncoder.encode(”메세지내용”)

  • 브라우저가 URL 인코딩을 해줄 수 없어 직접 (수동) URL 인코딩 해줘야 함.
  • JSP 에서 인코딩 내용 안보이는 경우 - 디코더
    • import 필요
<%@ page import="java.net.URLDecoder"%>
<div id="msg" class="msg"> ${URLDecoder.decode(param.msg, "utf-8")}</div> 

 

2. Model 저장

  • redirect는 재요청으로 model은 요청마다 독립적으로 존재하는 저장소이므로 컨트롤러에 매핑된 메서드가 전달하는 view에만 데이터 전달
			// (2) model 저장 - 여러 msg 전달 용이 
			model.addAttribute("msg", msg);
			return "redirect:/register/add"; // 재요청 redirect , model은 /add 요청에 사용 불가. /save에만 가능
				// return "redirect:/register/add?msg"+msg로 Spring이 자동으로 바꿔줌. 동일함.

 

 

TIP maven 의존성 파일 충돌로 인한 에러 해결

  • .m2 의 repository 폴더 삭제 > maven project update 로 다시 의존성 다운 받기
  • .m2 폴더 삭제 하면 안됨

 

TIP 파일명에 -source.jar 로 끝나는 파일의 확장자 zip으로 바꾸면 소스코드 볼 수 있음

.m2 폴더 내부의 -source.zip
zip으로 확인할 수 있는 java 파일들

 

 

redirect와 forwarding

redirect vs. forward 차이 ⭕ 면접, 암기

  • redirect 요청 2번, 응답 2번, 협력관계
  • forward 요청 1번, 응답 1번

redirect

  • 응답 헤더만 존재 O, body 없음 X
  • HTTP 상태코드 : 300 응답
  • 요청 2개, 응답 2개
  1. 수동 요청 GET, POST
  2. 자동 요청 : 브라우저가 다른 URL로 재요청 GET

ex. 담당자왈 “ 다른 부서로 다시 전화해주세요~” 고객이 다시 담당자에게 말해야함

 

redirect 방식

 

forward

클라이언트가 요청한 내용 중 일부만 처리하거나, 클라이언트의 내용을 다른 jsp에 그대로 request 객체로 전달

요청 1번 응답 1번

  • 요청 메서드의 method 유지 (절대 바뀌지 않음) ex. 원래 클라이언트 요청이 POST이면, forward로 요청하는 메서드도 무조건 POST
  • 에러 . 허용되지 않는 메서드

다른 jsp에서 request/response 객체 2개 전달 가능

ex. 담당자왈 “분실 담당자님 고객 문제 처리해주시고 전달해주세요” - 고객이 1번만 요청하면 됨.

 

forward
forward 네트워크 - 요청 1개

 

View -3

1. Redirect View

redirect view

과정

  1. 사용자의 요청을 DispatcherServlet이 받음
  2. Dispatcher Servlet이 요청을 처리할 수 있는 (url과 매핑된 )컨트롤러 메서드 호출
  3. Controller 메서드가 redirect:문자열이 반환하면 Dispatcher Servlet이 받음
  4. Dispatcher Servlet이 redirect가 포함된 것을 확인 후 Redirect View에 전달
  5. RedirectView가 응답헤더 생성
  6. 클라이언트가 응답헤더 받아 Location 보고 자동으로 요청함

Location 재요청할 url

  • 첫번째 요청 save
  • 두번쨰 요청 add?msg=내용 → 브라우저가 300번대 응답 받으면 자동 요청해줌

response 헤더

 

2. JSTL View

일반적인 경우 

JSTL View

과정

  1. 사용자의 요청을 DispatcherServlet이 받음
  2. Dispatcher Servlet이 요청을 처리할 수 있는 (url과 매핑된 )컨트롤러 메서드 호출
  3. Controller 메서드가 뷰이름을 Dispatcher Servlet으로 전달
  4. Dispatcher Servlet이 뷰이름을 InternalResourceViewResolver 에 전달
  5. InternalResourceViewResolver 가 뷰이름 해석(/WEB-INF/views/뷰이름.jsp) 후 진짜 이름 JstlView로 반환
  6. JstlView가 해당 jsp에게 Model 넘겨줌
  7. jsp가 최종 응답 생성 후 클라이언트에 전달

JstlView

  • JSP 뷰 처리

InternalResourceViewResolver

  • 접두사, 접미사 설정
  • 참고 Ch03

servlet-context.xml 웹관련 설정파일 - InternalResouceViewResolver

 

3. InternalResourceView

forward:/register/add
내부 요청이 한번 발생한 경우 (Controller에게 응답이 간 경우)

 

사용 상황

  • forward 할 때 사용하는 view
  • 은행 1년치 입출력 내용 pdf, csv, excel 뷰 만들기 ex. /download?type=pdf

과정

  1. 사용자의 요청을 DispatcherServlet이 받음
  2. Dispatcher Servlet이 요청을 처리할 수 있는 (url과 매핑된 )컨트롤러 메서드 호출
  3. Controller 메서드가 forward:문자열을 Dispatcher Servlet으로 반환
  4. Dispatcher Servlet이 forward를 보고 InternalResourceView에게 문자열 전달
  5. InternalResourceView 가 문자열을 호출하라고 Dispatcher Servlet에게 내부적으로(forwarding) 전달
  6. Dispatcher Servlet이 해당 메서드 호출 후 뷰이름 반환 (일반적인 프로세스 동일 4번부터, jstl view)

 

 

참고

- Spring의 정석 강의 및 교안, 남궁성 

  •