국비교육(22-23)

59일차(2)/Spring Boot(6) : WebConfig 설정, yml 파일 작성하기

서리/Seori 2022. 12. 30. 13:35

59일차(2)/Spring Boot(6) : WebConfig 설정, yml 파일 작성하기

 

- 새 프로젝트 생성

Boot06_WebConfig / 패키지명 com.sy.boot06

 

- 조건은 기본 2개만 선택

- 만약 선택한 내용을 고정하고 싶다면 체크한 상태로 하단의 Make Default를 누르면 디폴트 상태로 고정된다.

 

 

com.sy.boot06.config 패키지 생성

WebConfig 클래스

package com.sy.boot06.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.sy.boot06.MyInterceptor;

/*
 * [ Spring MVC 관련 설정 ] 
 * 
 * 1. WebMvcConfigurer 인터페이스를 구현한다.
 * 2. 설정에 필요한 메소드를 오버라이딩한다.
 *    주로 Resource Handler, Interceptor, view page 관련 설정을 여기서 한다.
 * 3. 설정에 관련된 클래스에는 @Configuration 어노테이션을 붙여야 한다.
 */

@Configuration
@EnableWebMvc //스프링이 자동 설정해주는 모든 기능을 사용하기 위해서 붙여주어야 한다.
public class WebConfig implements WebMvcConfigurer {
	/*
	 * servlet-context.xml에서 설정했던
	 * webapp/resources/ 안에 있는 내용을 서비스하기 위한
	 * 
	 * <resources mapping="/resources/**" location="/resources/" />
	 * 
	 * 아래를 설정하면 webapp에 resources 폴더를 만들어 놓고 그 안에 들어 있는 내용에 대한 요청은
	 * spring 프레임워크를 거치지 않고 바로 응답되게 할 수 있다.
	 * - SmartEditor2나 프로필 이미지를 저장할 upload 폴더를 만들 예정
	 */
	
	//여기서 bean으로 관리되는 MyInterceptor 객체가 필요하다면...
	
	@Autowired MyInterceptor inter;
	
	//@Autowired 어노테이션에서 주입받은 객체를 이 메소드에서 활용하면 된다.
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(inter)
		 .addPathPatterns("/users/*")
		 .excludePathPatterns("/users/loginform");
	}
	
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}
	
	//view page의 prefix, suffix 설정
	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/views/", ".jsp");
	}
}

 

- WebMvcConfigurer 를 구현한다.

 

 [ Spring MVC 관련 설정 ] 
1. WebMvcConfigurer 인터페이스를 구현한다.
2. 설정에 필요한 메소드를 오버라이딩한다.
   주로 Resource Handler, Interceptor, view page 관련 설정을 여기서 한다.
3. 설정에 관련된 클래스에는 @Configuration 어노테이션을 붙여야 한다.

 

- 인터셉터- 로그인 인터셉터 등을 사용하려면 여기에 설정해주어야 한다.

 

 

** Resource Handler란??

 

- 기존 Spring04_final 에서 보면 이런 것이 있다.

 이 안의 요청은 스프링 컨트롤러를 거치지 않는다는 설정!

- application.properties 에서는 이 설정이 되지 않는다.

 

- 그래서 WebConfig에서 이 설정을 할 것이다!

- 이 설정을 똑같이 해주어야만 이전 프로젝트를 큰 수정없이 Spring Boot로 이식할 수 있다.

 

addResourceHandlers 를 오버라이드 해주기

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}

 

.addResourceHandler()

- String... 을 받는다고 되어있는데, 이는 인자의 개수가 동적이라는 뜻이다.

- 인자를 하나 /두개 / 세개 ... 원하는대로 전달해도 된다는 것이다.

ex) ("aaa") / ("aaa", "bbb") / ("aaa", "bbb", "ccc") 모두 가능. String 배열로 받아진다.

 

- 이렇게 작성해주면 webapp-resources 폴더 안에 있는 것들은

 spring controller를 거치지 않고 사용할 수 있다.

 

- static과 비슷하지만 따로 만들어 주는 이유는? 여기에는 jsp를 만들 수 없어서...

 

- 기존 Spring 프로젝트에 들어있던 smartEditor를 사용할 수 없다. 이 안에도 jsp 파일이 있기 때문에!

- 그래서 똑같은 resources 폴더를 만들어주어야 한다.

 

- servlet-context.xml에서 설정했던 webapp/resources/ 안에 있는 내용을 서비스하기 위한
  <resources mapping="/resources/**" location="/resources/" />   를 설정하면 

  webapp에 resources 폴더를 만들어 놓고 그 안에 들어 있는 내용에 대한 요청은
  spring 프레임워크를 거치지 않고 바로 응답되게 할 수 있다.

 

- WebConfig 에 이렇게 접두어, 접미어 설정까지 해주면 된다.

(이것은 application.properties에서 하면 안 먹는다. 해도 소용이 없다.. 여기서 해야한다!)

 


 

앞선 Boot05 프로젝트에서 webapp 폴더, HomeController 를 복사해오고

pom.xml에서 jsp 페이지/jstl용 라이브러리도 가져와주기

 

home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/main/webapp/WEB-INF/views/home.jsp</title>
</head>
<body>
	<div class="container">
		<h1>인덱스 페이지 입니다.</h1>
		<%-- Spring Boot 에서 추가된 static 폴더에 있는 자원 사용하기 --%>
		<img src="${pageContext.request.contextPath}/images/cinnamo2.jpg" />
		<%-- 
			Resources Handler 설정으로 추가한 resources 폴더에 있는 자원 사용하기 
			static 폴더와 달리 jsp 페이지도 가능하다.
		--%>
		<img src="${pageContext.request.contextPath}/resources/images/apple.jpg" />
		<br />
		<a href="${pageContext.request.contextPath}/resources/test.jsp">jsp 페이지 사용</a>
		<br />
		<p>아래의 링크를 클릭해서 system 콘솔 창에 MyInterCeptor 가 관여하는지 안하는지 확인</p>
		<a href="${pageContext.request.contextPath}/users/info">인터셉터 동작확인</a>
		<a href="${pageContext.request.contextPath}/users/loginform">인터셉터 동작확인2</a>
		<h3>공지사항</h3>
		<ul>
			<c:forEach var="tmp" items="${noticeList }">
				<li>${tmp }</li>
			</c:forEach>
		</ul>
	</div>
</body>
</html>

 

- webapp-resources 폴더 생성

- 이 안에 html, css, js 등등을 넣을 수 있다(static에 넣을 수도 있다)

 

- images 폴더 만들어주기

 

- 두개의 폴더에 각각 이미지를 한개씩 넣어주고, home.jsp에서 해당 이미지를 출력해보기

 

 

 

- 이미지가 둘다 잘 나온다.

 


 

- jsp 링크도 추가해주기!(static 폴더에는 넣을 수 없다)

 

resources/test.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/webapp//resources/test.jsp</title>
</head>
<body>
	<h1>jsp 페이지입니다.</h1>
</body>
</html>

 

- resources에 넣은 페이지를 이렇게 응답하게 할 수 있다. 경로 보기!

- jsp가 잘 동작하므로, 이곳에 SmartEditor를 넣어서 사용할 수 있다.

 

- WebConfig 작성하기 :

 WebMvcConfigurer 구현해서 클래스를 만들고,

 또한 jsp페이지는 직접 메소드를 사용해서 등록해야 한다.

- prefix, suffix 설정 메소드로 설정 (configureViewResolvers)

 

- 위에는 @EnableWebMvc 를 추가해주기

- 스프링이 자동 설정해주는 모든 기능을 사용하기 위해서 붙여주어야 한다.

 (그런데 붙이면 static에 있는 이미지는 나오지않는다)

- 어노테이션 2개 확인.

 

- (jsp관련) 뷰 페이지 설정은 application.properties 에서 하는 것이 아니라

  WebConfig에서 하는 것으로 생각하기!!

 

 

- 각각 static에 있는 자원과 resources에 있는 자원에 접근하는 방법

- 그런데 이제 static 폴더를 굳이 쓸 필요가 없다. jsp도 못 쓰는데..

  굳이 static폴더를 관리하지 말고 앞으로 그냥 resources폴더를 사용하기로 함!

 


 

- interceptor도 WebConfig 에서 설정해준다.

 

MyInterceptor

package com.sy.boot06;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

//Spring이 관리하는 bean이 될 수 있도록 필요한 어노테이션
@Component
public class MyInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("나의 인터셉터가 끼어들었음!");
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		
	}
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		
	}
}

 

- Spring에서는 인터셉터를 xml 파일에서 bean으로 만들었음

- 어떤 요청에 대해서 끼어들지(interceptor), 또는 exclude 할 지 아래에 적어주었다.

 

 

- 그럼 Boot에서는 어떻게 끌어다가 사용하는가?

→ WebConfig 파일에서 끌어다가 사용한다.

 

- Component로 bean이 되어있으면 Interceptor도 @Autowired 를 사용해서 주입받으면 된다.

 

addInterceptors()

- interceptor registry를 전달받는 객체가 있다.

 

- 어떤 경로에 관여하는지, 어떤 경로에서는 제외하는지는 이 뒤에서!

 addPathPattens() 에 넣어준다.

 

- 여기에 각각 등록해준 것이다.

 

 

- Spring Boot WebConfig를 사용하면서

 경로 mapping 은 분홍색, exclude-mapping 은 주황색 화살표로 각각 바뀐 것을 확인하기!

 

 

- home에 인터셉터 테스트링크 추가

 

- 실행 후 콘솔창에서 확인해보면,

/info 경로 요청에는 interceptor가 끼어들고,

/loginform 경로 요청에서는 끼어들지 않는다.(exclude됨)

 

 


 

- WebConfig 에서는 @EnableWebMvc  일단 빼기!

 

- 일단 2가지는 주석 처리했다.

 

- prefix, suffix 설정은 application.properties로 바꾸어주엇다.

 

 

- 그리고 application.properties 이름을 바꾸어주려고 한다! 

 

application.yml (Rename으로 바꾸면 된다)

 

- 그러면 Yaml 파일로 바뀌고, 작성하는 방식이 달라진다. (자동완성으로 저렇게 작성할 수 있다)

 

 

- Yaml 파일 전용으로 열어준다. (대신 한글 사용은x)

 

 

- Yaml 야믈 파일이라고 한다.

 

- 이렇게 작성해주기 (ctrl+space 자동완성으로 보기쉽게 작성가능)

 

- 'yml 작성법' 구글 검색해보기

- 위와 같이 계층구조를 만들어서 중복을 없앨 수 있다.