1. index.jsp 추가
- 기존에는 서버실행 시 home.jsp가 실행됨
- 하지만 보통 웹사이트의 경우 index.jsp가 실행됨
- src/main/webapp 디렉토리 밑에 index.jsp 추가
<body>
<h1>Hello World</h1>
</body>
2. web.xml 변경
- web.xml에 다음 내용 추가
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<web-app></web-app> 태그 사이에 추가
3. 서버 실행
- Tomcat Run
- http://localhost:8080/"프로젝트명"/ 입력
4. 서블릿 설정 변경
- 서블릿(Servlet) : 자바에서 동적 웹 프로젝트를 개발할 때, 사용자의 요청과 응답을 처리해 주는 역할
- 보통 스프링에서는 servlet 설정이 .do로 되어있는데, 기본 프로젝트에서는 .do로 되어있지 않음. 따라서, 서블릿 설정을 변경
- web.xml에 <servlet> 및 <servlet-mapping> 부분 수정.
<!-- 기존 servlet 설정
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern>
</servlet-mapping>
-->
<!-- servlet 설정 변경 -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/config/*-servlet.xml </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
여기서 볼 것은 <url-pattern>*.do</url-pattern> 부분이다.
이는 앞으로 서블릿에 어떠한 요청을 할 때, .do를 통해서만 요청을 전달하고, 다른 방식의 요청, 예를 들어 .html의 직접적인 호출등은 이제 허락되지 않는다.
그 다음 확인할 부분은 contextConfigLocation의 설정이다.
기존에는 dispatcher 의 설정인 contextConfigLocation이 /WEB-INF/spring/appServlet/servlet-context.xml에 존재하였는데, 이를 /WEB-INF/config/action-servlet.xml로 변경하고, 인터셉터(Intercepter)도 추가하려는 목적이다. 인터셉터에 대한 설명은 다음 글에서 하려고 한다.
5. contextConfigLocation 변경
- /WEB-INF 디렉토리 밑에 config 라는 폴더를 만듦
- /WEB-INF/spring/appServlet 디렉토리에 있는 servlet-context.xml을 복사해서, /WEB-INF/config 폴더에 붙여넣고, 이름을 action-servlet.xml로 변경
- /WEB-INF/에 있는 spring이라는 디렉토리를 삭제한다.
6. 설정파일 변경 (web.xml, action-servlet.xml 등)
- web.xml 수정. 다음 내용 추가 (UTF-8설정)
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
- Spring 설정파일 추가
기존 <context-param> 태그의 <param-value> 태그안에는 아마 아무것도 작성되지 않았을 것임. 스프링 설정파일을 읽어오기 위해서 다음과 같이 바꾼다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value> classpath*:config/spring/context-*.xml
</param-value>
</context-param>
7. Log4j 설정
- log4j.xml 변경
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- 변경된 log4j.xml -->
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
</layout>
</appender>
<appender name="console-infolog" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="hmg" additivity="false"> <!-- logger name은 최상위 package 명으로 설정 -->
<level value="debug" />
<appender-ref ref="console"/>
</logger>
<!-- Query Loggers -->
<logger name="jdbc.sqlonly" additivity="false">
<level value="INFO"/>
<appender-ref ref="console-infolog"/>
</logger>
<logger name="jdbc.resultsettable" additivity="false">
<level value="INFO"/>
<appender-ref ref="console"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="off"/>
<appender-ref ref="console" />
</root>
</log4j:configuration>
8. Interceptor 설정
- 인터셉터는 중간에 무엇인가를 가로챈다는 의미이다. 스프링에서도 말 그대로 중간에 요청을 가로채서 어떠한 일을 하는것을 의미한다. 서블릿(Servlet)을 사용해본 사람이라면 필터(Filter)를 들어봤을텐데, 비슷한 의미로 사용된다. 그럼 어느 중간에서 요청을 가로채서 무엇을 하는지를 간단히 살펴보자.
인터셉터는 위 이미지의 빨간색 박스 부분에서 동작한다. 인터셉터의 정확한 명칭은 핸들러 인터셉터 (Handler Interceptor)이다. 인터셉터는 DispatcherServlet이 컨트롤러를 호출하기 전,후에 요청과 응답을 가로채서 가공할 수 있도록 해준다.
예를 들어, 로그인 기능을 구현한다고 했을때, 어떠한 페이지를 접속하려고 할때, 로그인된 사용자만 보여주고, 로그인이 되어있지 않다면 메인화면으로 이동시키려고 해보자. 기존에는 로그인 체크 로직을 만들어서 각 화면마다 일일이 Ctrl + C,V로 만들기도 했다.
스프링에서는 인터셉터를 사용하여 위의 기능을 간단히 만들 수 있다.
인터셉터에서 어떠한 요청이 들어올 때, 그 사람의 로그인 여부를 판단해서 로그인이 되어있으면 요청한 페이지로 이동시키고, 로그인이 되어있지 않을경우 바로 메인 페이지로 이동시키면 끝이다.
즉, 단 하나의 인터셉터로 프로젝트내의 모든 요청에서 로그인여부를 관리할 수 있는것이다.
- 먼저 src/main/java/"hmg"(상위패키지명) 패키지 내에 common 패키지를 생성하고 그 밑에 logger 패키지를 생성
마찬가지로 HomeController.java도 삭제한다.
- logger 패키지 밑에 LoggerInterceptor.java를 생성 (현재 호출된 URI이 무엇인지 출력해주는 인터셉터)
인터셉터는 HandlerInterceptorAdapter 클래스를 상속받아서 만든다.
HandlerInterceptorAdapter에서는 사용할 수 있는 몇가지 메서드들이 있는데 우리는 일단 두가지만 구현하려고 한다. 전처리기와 후처리기가 바로 그것인데, 위에서 client -> controller 로 요청할 때, 그 요청을 처리할 메서드 하나(전처리기)와 controller -> client 로 응답할 때, 그 요청을 처리할 메서드 하나(후처리기)를 만들 예정이다.
package hmg.comm.logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class LoggerInterceptor extends HandlerInterceptorAdapter {
protected Logger log = LoggerFactory.getLogger(LoggerInterceptor.class);
// 전처리기 (Client -> Controller(Dispatcher) 요청 시 처리 작업)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (log.isDebugEnabled()) {
log.debug("====================================== START ======================================");
log.debug(" Request URI \t: " + request.getRequestURI());
}
return super.preHandle(request, response, handler);
}
// 후처리기 (Controller(Dispatcher) -> Client 요청 시 처리 작업)
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
if (log.isDebugEnabled()) {
log.debug("====================================== END ======================================\n");
}
}
}
- 방금 만든 인터셉터를 등록한다.
action-servlet.xml 다음으로 수정
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- base-package는 자신의 상위패키지명으로 변경 -->
<context:component-scan base-package="hmg"></context:component-scan>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<!-- class는 자신의 상위패키지명으로 변경 -->
<bean id="loggerInterceptor"
class="hmg.comm.logger.LoggerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.view.BeanNameViewResolver"
p:order="0" />
<bean id="jsonView"
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
<bean
class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:order="1"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp">
</bean>
</beans>
스프링 3.2 이상에서는 mvc를 설정하는게 많이 바뀌었다.
<mvc:mapping path/>를 통해서 인터셉터가 동작할 URL을 지정할 수 있다. 지금 작성하는 로거는 모든 요청에서 동작을 하기때문에 전체 패스를 의미하는 "/**" 로 설정하였다.
그 후, bean을 수동으로 등록한다.
중요!!! 위에서 이야기 했듯이, Interceptor는 Controller가 요청되기 전에 수행된다. 즉, Interceptor는 DispatcherServlet과 같은 위치에 등록이 되어있어야지 정상적으로 수행이 된다.
DispatcherServlet은 사용자(클라이언트)의 요청을 받아서 해당 요청에 매핑되는 컨트롤러와 연결한 후, 컨트롤러에서 정의된 view를 사용자의 브라우저에 출력하는 역할을 수행한다.
web.xml을 다시한번 살펴보자.
<servlet>
<servlet-name>action</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/config/*-servlet.xml </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
우리는 여기서 이미 DispatcherServlet을 정의하였다. 그리고 그 DispatcherServlet의 설정파일의 위치는 /WEB-INF/config/ 폴더 밑의 -servlet.xml 로 끝나는 모든 xml 파일이라고 명시한 것이다.
즉, action-servlet.xml에 interceptor를 설정함으로써, 우리는 DispatcherServlet과 Interceptor를 같은 위치에 등록을 한것이다.
만약, action-servlet에서 Interceptor의 설정을 분리하여 다른 파일로 만들고싶으면, action-servlet.xml이 있는 폴더에 *-servlet.xml의 이름 형식 (예를 들어 interceptor-servlet.xml )으로 만들면 된다.
- 이제 인터셉터가 제대로 동작하는지 확인하자.
- src/main/java/hmg 밑에 sample.controller 패키지를 만든다.
- controller 패키지에 SampleController 클래스를 생성하고 다음 소스 입력
package hmg.sample.controller;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class SampleController {
Logger log = LoggerFactory.getLogger(this.getClass());
@RequestMapping(value = "/sample/openSampleList.do")
public ModelAndView openSampleList(Map<String, Object> commandMap) throws Exception {
ModelAndView mv = new ModelAndView("");
log.debug("인터셉터 테스트");
return mv;
}
}
- index.jsp 변경, /sample/openSampleList.do 호출하도록 변경
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<jsp:forward page="/sample/openSampleList.do" />
- 서버실행 후 http://localhost:8080/"프로젝트명"/ 접속
eclipse에 다음과 같은 로그 찍히는지 확인
2019-07-13 01:32:55,000 DEBUG [hmg.comm.logger.LoggerInterceptor] ====================================== START ======================================
2019-07-13 01:32:55,001 DEBUG [hmg.comm.logger.LoggerInterceptor] Request URI : /hmgWebapp/sample/openSampleList.do
2019-07-13 01:32:55,020 DEBUG [hmg.sample.controller.SampleController] 인터셉터 테스트
2019-07-13 01:32:55,021 DEBUG [hmg.comm.logger.LoggerInterceptor] ====================================== END ======================================
출처: https://addio3305.tistory.com/39?category=772645 [흔한 개발자의 개발 노트]
'DEV > Spring' 카테고리의 다른 글
[Spring] 6. Gitlab과 Jenkins 연동 (0) | 2019.07.13 |
---|---|
[Spring] 5. Ubuntu 서버 기본 설정 (0) | 2019.07.13 |
[Spring] 4. Eclipse와 GitLab 연동하기 (0) | 2019.07.13 |
[Spring] 3. 네이버 클라우드 이용한 Ubuntu 서버 생성 (0) | 2019.07.13 |
[Spring] 1. 초기 환경 설정 (0) | 2019.07.13 |
댓글