스프링

 

스프링 부트 ( 2.7.0)    mybatis  사용

 

 

인터셉터 설정

 

sts-interceptor-12-01

인터셉터란? 가로챈다는 뜻이다.

스프링의 Spring Context(ApplicationContext)기능으로 인터셉터는 임의의 URI를 호출시 DispatcherServlet에서 해당 Controller가 처리 되기 전과 후에 발생하는 이벤트이다. 비슷한 역할로는 필터(Filter)가 있다. 둘다 역할은 비슷하지만 차이가 있다.

 

 

 

1. BaseHandlerInterceptor 추가
 

BaseHandlerInterceptor

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

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BaseHandlerInterceptor implements HandlerInterceptor {

	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("\n\n\n*** [preHandle] URI : {} - 시작 " , request.getRequestURI());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    	log.info("\n***[postHandle] URI  : {}  - 종료 \n\n\n", request.getRequestURI());
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) throws Exception {
    	//log.info("[afterCompletion]");
    }
	
}

 

 

 

2. WebMvcConfig  클래스에서 WebMvcConfigurer  인터페이스 구현

 

import org.springframework.boot.web.servlet.view.MustacheViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

import kr.so.songjava.configuration.handler.BaseHandlerInterceptor;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

	/**
	 * 머시태시 템플릿을 html 확장자 명으로 변경
	 */
	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		MustacheViewResolver resolver = new MustacheViewResolver();

		resolver.setCharset("UTF-8");
		resolver.setContentType("text/html;charset=UTF-8");
		resolver.setPrefix("classpath:/templates/");
		resolver.setSuffix(".html");

		registry.viewResolver(resolver);
	}

	/**
	 * Locale 값이 변경되면 인터셉터가 동작한다. url의 query parameter에 지정한 값이 들어올 때 동작한다. ex)
	 * http://localhost:8080?lang=ko
	 * 
	 * @return
	 */
	@Bean
	public LocaleChangeInterceptor localeChangeInterceptor() {
		LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
		interceptor.setParamName("lang");
		return interceptor;
	}

	
	/**
	 *  BaseHandlerInterceptor 빈 설정
	 */
	@Bean
	public BaseHandlerInterceptor baseHandlerInterceptor() {
		return new BaseHandlerInterceptor();
	}
	
	
	/**
	 * 인터셉터 등록 LocaleChangeInterceptor 를 스프링 컨테이너에 등록한다. WebMvcConfigurer 를 상속받고
	 * addInterceptors를 오버라이딩 한다.
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 로그을 찍기 위해  - BaseHandlerInterceptor 인터셉터 등록
		registry.addInterceptor(baseHandlerInterceptor());
		
		//다국어 설정을 위한 localeChangeInterceptor 을 인터셉터에 등록
		registry.addInterceptor(localeChangeInterceptor());
	}
	
	
}

 

 

 


3. application.properties  설정

 

# logback 위치지정
logging.config= classpath:logback/logback-default.xml

 

 

 


4. logback-default.xml  추가
 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<include resource="org/springframework/boot/logging/logback/base.xml"/>
 
      <!-- 1. 유형 - 콘솔로 로그를 남김 색깔 적용 -->
     <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
              <withJansi>true</withJansi>
              <encoder>
                       <charset>UTF-8</charset>
                       <!-- 로그 메시지 패턴 -->
                       <Pattern>
                               %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n
                       </Pattern>
              </encoder>
     </appender>
         
      <!-- 2.유형 : 파일로 로그를 남김 -->      
	<appender name="dailyRollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<prudent>true</prudent>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>logs/applicatoin.%d{yyyy-MM-dd}.log</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>error</level>
		</filter>
 
		<encoder>
			<pattern>%d{yyyy:MM:dd HH:mm:ss.SSS} %-5level --- [%thread] %logger{35} : %msg %n</pattern>
		</encoder>
	</appender>


        <!-- 3.유형 : 파일로 로그를 남김 -->
       <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- <file>c:\LogExample\logexample2.log</file> -->
                <file>logs/logexample2.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                         <Pattern>
                                 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n
                         </Pattern>
                </encoder>

                <!-- 로그를 남기는 파일의 용량이 50KB가 넘으면 이를 압축 파일로 만들고 새로 로그 파일로 만들라는 정책 -->
                <triggeringPolicy  class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                         <MaxFileSize>50KB</MaxFileSize>
                </triggeringPolicy>


                <!-- 파일을 덮어쓰는 정책 -->
                 <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!--                   <FileNamePattern>C:\LogExample\logexample2.%i.log.zip</FileNamePattern> -->
                         <FileNamePattern>logs/zip/logexample2.%i.log.zip</FileNamePattern>
                         <!--
                             MinIndex가 1이고, MaxIndex가 10이므로, 위의 파일 이름 패턴에 따라 아래의 로그 파일이 생길 것이다.
                             logexample2.1.log.zip   logexample2.2.log.zip  .... logexample2.10.log.zip
                             이 상태에서 또 10KB가 넘으면 logexample2.1.log.zip이 된다.
                         -->
                         <MinIndex>1</MinIndex>
                         <MaxIndex>10</MaxIndex>
                </rollingPolicy>
       </appender>
	
	
 
	<logger name="org.springframework.web" level="info"/>
	<logger name="org.thymeleaf" level="info"/>
	<logger name="org.hibernate.SQL" level="info"/>
	<logger name="org.quartz.core" level="info"/>
	<logger name="org.h2.server.web" level="info"/>
	<logger name="org.mariadb.jdbc" level="info"/>
	<logger name="org.mysql.jdbc" level="info"/>

	<!-- log4jdbc 옵션 설정 -->
	<logger name="jdbc" level="OFF" /> <!-- 커넥션 open close 이벤트를 로그로 남긴다. -->
	<logger name="jdbc.connection" level="OFF" /> <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. -->
	<logger name="jdbc.sqlonly" level="OFF" /> <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. -->
	<logger name="jdbc.sqltiming" level="DEBUG" /> <!-- ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. -->
	<logger name="jdbc.audit" level="OFF" /> <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. -->
	<logger name="jdbc.resultset" level="OFF" /> <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. -->
	<logger name="jdbc.resultsettable" level="info" />
 
 	<logger name="springfox" level="WARN"/>
 	<logger name="org.hibernate" level="WARN"/>
 	<logger name="org.apache" level="WARN"/>
 	<logger name="org.apache.http.imp.conn" level="WARN"/>
 
 
 
 	<!-- root는 글로벌 로거를 의미하며, 위의 logger에 해당하지 않으면 root 로거가 실행된다. -->
	<root level="info">
		<!-- 3.유형 로그 사용 -->
		<appender-ref ref="fileAppender" />
	</root>
</configuration>

 

 

 

5. DriverSpy 라이브러리 사용 및 SQL 로그 보기

 

1) 라이브러리 등록

		<dependency>
		  <groupId>org.bgee.log4jdbc-log4j2</groupId>
		  <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
		  <version>1.16</version>
		</dependency>

 

 

2) log4jdbc.log4j2.properties  파일을   resouces 위치에  생성후 다음과 같이 입력

 

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0

 

 

3) application.properties

드라이브 클래스네임 다음과 같이 변경

spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy

jdbc와  mysql 사이에 log4jdbc 추가

jdbc:log4jdbc:mysql:

#MySQL 연결설정
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/songjava?serverTimezone=UTC
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/songjava?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=songjava
spring.datasource.password=1111

 

 

 

 

6. 로그 최대한 출이기

 

 
	<logger name="org.springframework.web" level="info"/>
	<logger name="org.thymeleaf" level="info"/>
	<logger name="org.hibernate.SQL" level="info"/>
	<logger name="org.quartz.core" level="info"/>
	<logger name="org.h2.server.web" level="info"/>
	<logger name="org.mariadb.jdbc" level="info"/>
	<logger name="org.mysql.jdbc" level="info"/>

	<!-- log4jdbc 옵션 설정 -->
	<logger name="jdbc" level="OFF" /> <!-- 커넥션 open close 이벤트를 로그로 남긴다. -->
	<logger name="jdbc.connection" level="OFF" /> <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. -->
	<logger name="jdbc.sqlonly" level="OFF" /> <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. -->
	<logger name="jdbc.sqltiming" level="DEBUG" /> <!-- ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. -->
	<logger name="jdbc.audit" level="OFF" /> <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. -->
	<logger name="jdbc.resultset" level="OFF" /> <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. -->
	<logger name="jdbc.resultsettable" level="info" />
 
 	<logger name="springfox" level="WARN"/>
 	<logger name="org.hibernate" level="WARN"/>
 	<logger name="org.apache" level="WARN"/>
 	<logger name="org.apache.http.imp.conn" level="WARN"/>
 

 

 

 

 


7. LOG 파일로 남기기

        <!-- 3.유형 : 파일로 로그를 남김 -->
       <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- <file>c:\LogExample\logexample2.log</file> -->
                <file>logs/logexample2.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                         <Pattern>
                                 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n
                         </Pattern>
                </encoder>

                <!-- 로그를 남기는 파일의 용량이 50KB가 넘으면 이를 압축 파일로 만들고 새로 로그 파일로 만들라는 정책 -->
                <triggeringPolicy  class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                         <MaxFileSize>50KB</MaxFileSize>
                </triggeringPolicy>


                <!-- 파일을 덮어쓰는 정책 -->
                 <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!--                   <FileNamePattern>C:\LogExample\logexample2.%i.log.zip</FileNamePattern> -->
                         <FileNamePattern>logs/zip/logexample2.%i.log.zip</FileNamePattern>
                         <!--
                             MinIndex가 1이고, MaxIndex가 10이므로, 위의 파일 이름 패턴에 따라 아래의 로그 파일이 생길 것이다.
                             logexample2.1.log.zip   logexample2.2.log.zip  .... logexample2.10.log.zip
                             이 상태에서 또 10KB가 넘으면 logexample2.1.log.zip이 된다.
                         -->
                         <MinIndex>1</MinIndex>
                         <MaxIndex>10</MaxIndex>
                </rollingPolicy>
       </appender>
	

 

 

 

 

 

소스 :

https://github.com/braverokmc79/sprig_boot_2.7.0_mybatis_board_project/commit/c65edb0b02cdaf1f267fccbb07fbf2a1fb7b0f52

 

 

 

 

 

 

참조:

1) https://linked2ev.github.io/gitlog/2019/09/15/springboot-mvc-12-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-MVC-Interceptor-%EC%84%A4%EC%A0%95/

2) https://congsong.tistory.com/24

 

 

3)Spring Boot Logback 설정

4)  logback-spring.xml 설정방법

 

 

about author

PHRASE

Level 60  라이트

장딴지와 정강이에 털이 닳아서 없다. 세상 일에 분주한 것. -장자

댓글 ( 4)

댓글 남기기

작성