반응형

사용 된 기술 :   Java SE 1.8 | Log4j 2.8.2 | 메이븐 3.3.9 | Jackson API 2.8.7 | Eclipse Neon.3

RollingFileAppender는 특정 크기 제한에 도달하거나 날짜 / 시간 패턴이 더 이상 적용되지 않으면 로그 파일을 롤오버하는 파일 첨부 프로그램입니다.

이 글에서는,를 사용 RollingFileAppender하여 이전 로그 파일을 백업하고 압축하는 방법을 설명합니다 

Jar dependencies

pom.xml 파일을 편집하고 log4j2 및 Jackson API 종속성을 추가하십시오.

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.8.2</version>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.8.2</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.8.7</version>
  </dependency>

  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.7</version>
  </dependency>

  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.7</version>
  </dependency>
</dependencies>

날짜 및 시간을 기준으로 롤링

TimeBasedTriggeringPolicy 를 사용하여 <FilePattern/>다음과 같이 요소에 사용 된 날짜 및 시간 패턴을 기반으로 로그 파일을 롤오버 할 수 있습니다 .

<RollingFile name="RollingFile">
  <FileName>C:/log/mylog.log</FileName>
  <FilePattern>C:/log/time-based-logs/%d{yyyy-MM-dd-hh-mm}.log.zip</FilePattern>
  <PatternLayout>
    <Pattern>%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n</Pattern>
  </PatternLayout>
  <Policies>
    <TimeBasedTriggeringPolicy interval="2" modulate="true" />
  </Policies>
  <DefaultRolloverStrategy max="5" />
</RollingFile>

다음은 날짜 / 시간에 기초한 파일 롤링의 날짜 / 시간 패턴 샘플입니다.

날짜 / 시간 패턴기술Intervale 속성 예
% d {yyyy-MM-dd-hh-mm} .log.zip매분마다 로그 파일 롤링

interval = 2이면 2 분마다 롤오버가 발생합니다.

예 :  2017-07-26-09-57.log.zip ,  2017-07-26-09-59.log.zip ,  2017-07-26-10-01.log.zip ,  2017-07-26- 10-03.log.zip 등 ..

% d {yyyy-MM-dd-hh} .log.zip로그 파일을 매 시간 롤업하십시오.

interval = 4이면 4 시간마다 롤오버가 발생합니다.

예 :  2017-07-26-09.log.zip ,  2017-07-26-10.log.zip ,  2017-07-26-11.log.zip  

% d {yyyy-MM-dd} .log.zip매일 로그 파일 롤링

interval = 1이면 롤오버가 매일 발생합니다.

예 :  2017-07-26.log.zip ,  2017-07-27.log.zip 등

다음은 log4j2.xml2 분마다 파일을 롤링하기위한 파일 의 전체 예제입니다  .

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>

    <!-- Console Appender -->
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
    </Console>

    <!-- Rolling File Appender -->
    <RollingFile name="RollingFile">
      <FileName>C:/log/mylog.log</FileName>
      <FilePattern>C:/log/time-based-logs/%d{yyyy-MM-dd-hh-mm}.log.zip</FilePattern>
      <PatternLayout>
        <Pattern>%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="2" modulate="true" />
      </Policies>
      <DefaultRolloverStrategy max="5" />
    </RollingFile>

  </Appenders>
  <Loggers>
    <Logger name="com.boraji.tutorial.log4j2" level="debug" additivity="false">
      <AppenderRef ref="RollingFile" />
      <AppenderRef ref="Console" />
    </Logger>
    <Root level="trace">
      <AppenderRef ref="Console" />
    </Root>
  </Loggers>
</Configuration>

<DefaultRolloverStrategy>요소를 제거하기 전에 5 개의 파일을 유지하는 롤오버 전략을 정의합니다.

위의 log4j 2 구성을 테스트하는 간단한 Java 프로그램.

MainApp.java

package com.boraji.tutorial.log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MainApp {

   private static final Logger logger = LogManager.getLogger(MainApp.class);

   public static void main(String[] args) {

      for (int i = 0; i < 10000; i++) {
         logger.info("Rolling file appender example...");
         try {
            Thread.sleep(500);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }

   }
}

 

파일 크기에 따른 롤링

SizeBasedTriggeringPolicy 를 사용하여 다음과 같이 파일 크기에 따라 로그 파일을 롤오버 할 수 있습니다 .

<RollingFile name="RollingFile">
  <FileName>C:/log/mylog.log</FileName>
  <FilePattern>C:/log/size-based-logs/%d{yyyy-MM-dd-hh}-%i.log.zip</FilePattern>
  <PatternLayout>
    <Pattern>%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n</Pattern>
  </PatternLayout>
  <Policies>
    <SizeBasedTriggeringPolicy size="10 KB"/>
  </Policies>
  <DefaultRolloverStrategy max="5" />
</RollingFile>

KB, MB 또는 GB 접미 부와 함께 파일 크기를 바이트 단위로 지정할 수 있습니다.

다음은 요소 log4j2.xml의 지정된 크기를 기반으로 파일 롤링을위한 전체  파일입니다 <SizeBasedTriggeringPolicy/>.

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>

    <!-- Console Appender -->
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
    </Console>

    <!-- Rolling File Appender -->
    <RollingFile name="RollingFile">
      <FileName>C:/log/mylog.log</FileName>
      <FilePattern>C:/log/size-based-logs/%d{yyyy-MM-dd-hh}-%i.log.zip</FilePattern>
      <PatternLayout>
        <Pattern>%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n</Pattern>
      </PatternLayout>
      <Policies>
        <SizeBasedTriggeringPolicy size="10 KB" />
      </Policies>
      <DefaultRolloverStrategy max="5" />
    </RollingFile>

  </Appenders>
  <Loggers>
    <Logger name="com.boraji.tutorial.log4j2" level="debug" additivity="false">
      <AppenderRef ref="RollingFile" />
      <AppenderRef ref="Console" />
    </Logger>
    <Root level="trace">
      <AppenderRef ref="Console" />
    </Root>
  </Loggers>
</Configuration>

다음은 위의 log4j2.xml 설정을 테스트하는 간단한 자바 프로그램이다.

package com.boraji.tutorial.log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MainApp {

   private static final Logger logger = LogManager.getLogger(MainApp.class);

   public static void main(String[] args) {

      for (int i = 0; i < 50000; i++) {
         logger.info("Rolling file appender example...");
      }

   }
}

cron 표현식을 기반으로 한 롤링

다음과 같이 CronTriggeringPolicy 를 사용하여 지정된 cron 표현식을 기반으로 로그 파일을 롤오버 할 수 있습니다 .

<RollingFile name="RollingFile">
  <FileName>C:/log/mylog.log</FileName>
  <FilePattern>C:/log/cron-based-logs/%d{yyyy-MM-dd-hh-mm}-%i.log.zip</FilePattern>
  <PatternLayout>
    <Pattern>%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n</Pattern>
  </PatternLayout>
  <Policies>
    <CronTriggeringPolicy schedule="0 0/2 * 1/1 * ? *" />
  </Policies>
  <DefaultRolloverStrategy max="5" />
</RollingFile>

다음은 cron 표현식에 의해 엘리먼트의 속성에 log4j2.xml지정된 매 2 분마다 롤오버를 트리거 하는 전체  파일 입니다.schedule<CronTriggeringPolicy/>

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>

    <!-- Console Appender -->
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
    </Console>

    <!-- Rolling File Appender -->
    <RollingFile name="RollingFile">
      <FileName>C:/log/mylog.log</FileName>
      <FilePattern>C:/log/cron-based-logs/%d{yyyy-MM-dd-hh-mm}-%i.log.zip</FilePattern>
      <PatternLayout>
        <Pattern>%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n</Pattern>
      </PatternLayout>
      <Policies>
        <CronTriggeringPolicy schedule="0 0/2 * 1/1 * ? *" />
      </Policies>
      <DefaultRolloverStrategy max="5" />
    </RollingFile>

  </Appenders>
  <Loggers>
    <Logger name="com.boraji.tutorial.log4j2" level="debug" additivity="false">
      <AppenderRef ref="RollingFile" />
      <AppenderRef ref="Console" />
    </Logger>
    <Root level="trace">
      <AppenderRef ref="Console" />
    </Root>
  </Loggers>
</Configuration>

다음은 위의 log4j2.xml 설정을 테스트하는 간단한 자바 프로그램이다.

package com.boraji.tutorial.log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MainApp {

   private static final Logger logger = LogManager.getLogger(MainApp.class);

   public static void main(String[] args) {

      for (int i = 0; i < 1000; i++) {
         logger.info("Rolling file appender example...");
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }

   }
}


반응형
반응형

기본적으로 Spring Boot 애플리케이션에서 'Starter'를 사용하는 경우 Logback 프레임 워크가 로깅에 사용됩니다. 

이 글에서는 Spring 부팅 애플리케이션에서 log4j 2 프레임 워크를 설정하는 방법을 배우게 될 것이다.

이 예제에 사용 된 도구 및 기술은 다음과 같습니다.

  • Spring Boot 1.5.8.RELEASE
  • Log4j 2.7
  • Maven 3.5.2
  • Eclipse Neon.3 (4.6.3)

예를 보자 ...

프로젝트 구조

다음과 같은 프로젝트 구조를 검토하십시오.

spring-boot-log4j.png

관련 -  이클립스 IDE에서 메이븐 프로젝트를 만드는 방법 .

Jar dependencies

우리가 알고있는 것처럼 기본적으로 의존 관계 관리를 위해 Starter 를 사용하는 경우 Logback이 로깅에 사용됩니다 스프링 부트 응용 프로그램에서 log4j 2를 사용하려면 Logback을 제외시킨 다음 log4j 2 Starter 를 다음과 같이 포함시켜야 합니다.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.boraji.tutorial.springboot</groupId>
  <artifactId>spring-boot-log4j2-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <java.version>1.8</java.version>
  </properties>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.8.RELEASE</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Log4j 2 구성

 src/main/resources폴더안에 log4j2.xml생성 후 파일을 그 안에 넣고, 다음과 같은 코드를 작성합니다.

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <!-- Console Appender -->
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
    </Console>
    <!-- File Appender -->
    <File name="File" fileName="d:/app.log">
      <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
    </File>
    
  </Appenders>

  <Loggers>
    <!-- Log everything in custom package -->
    <Logger name="com.boraji.tutorial.springboot" level="debug" additivity="false">
      <AppenderRef ref="Console" />
      <AppenderRef ref="File" />
    </Logger>

    <!-- Log everything in Spring Boot -->
    <Logger name="org.springframework.boot" level="debug" additivity="false">
      <AppenderRef ref="Console" />
      <AppenderRef ref="File" />
    </Logger>

    <!-- Log everything in Spring Core -->
    <Logger name="org.springframework.core" level="debug" additivity="false">
      <AppenderRef ref="Console" />
      <AppenderRef ref="File" />
    </Logger>

    <Root level="error">
      <AppenderRef ref="Console" />
      <AppenderRef ref="File" />
    </Root>
    
  </Loggers>
</Configuration>

 

Run application

주석으로 @SpringBootApplication 주석이 달린 메인 클래스를 작성  하여 log4j 2 구성을 다음과 같이 테스트하십시오.

MainApp.java

package com.boraji.tutorial.springboot;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MainApp {
  
  private static Logger logger = LogManager.getLogger(MainApp.class);

  public static void main(String[] args) {
    logger.info("Starting Spring Boot application..");
    SpringApplication app = new SpringApplication(MainApp.class);
    app.run(args);
  }
}

를 실행하면 MainApp.java콘솔 출력은 다음과 같이 보입니다.

spring-boot-log4j_01.png

소스 다운로드


반응형
반응형

이 글에서는 스프링 부트 프레임 워크를 사용하여 스프링 MVC 웹 애플리케이션을 만들고 부트 스트랩하는 방법을 설명하겠다. JSP를 웹 애플리케이션의보기로 사용합니다.

이 응용 프로그램에 사용되는 도구 및 기술은 다음과 같습니다.


  • Spring Boot 1.5.4.RELEASE
  • Spring WebMVC 4.3.9.RELEASE
  • Tomcat Embedded 8.5
  • JavaSE 1.8
  • Maven 3.3.9
  • Eclipse Neon.3


프로젝트 구조 

스프링 부트 프로젝트 구조를 검토하십시오.

spring-boot-mvc-jsp.png

관련 -  이클립스 IDE에서 메이븐 프로젝트를 만드는 방법 .

Jar dependencies

스프링 부트에서 스프링 MVC 웹 애플리케이션을 생성하고 실행하려면  파일에 spring-boot-starter 의존성  을 추가해야한다  pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

다음은 전체 pom.xml파일입니다.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.boraji.tutorial.springboot</groupId>
  <artifactId>spring-boot-web-application-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <java.version>1.8</java.version>
  </properties>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.4.RELEASE</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- JSTL tag lib -->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>javax.servlet.jsp.jstl-api</artifactId>
      <version>1.2.1</version>
    </dependency>

    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <!-- Tomcat for JSP rendering -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <scope>provided</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <packaging>war</packaging>
</project>

컨트롤러 클래스

 패키지 HelloController아래 에 클래스를 com.boraji.tutorial.springboot.controller만들고 다음 코드를 작성하십시오.

HelloController.java

package com.boraji.tutorial.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

   @RequestMapping("/")
   public String index() {
      return "index";
   }

   @PostMapping("/hello")
   public String sayHello(@RequestParam("name") String name, Model model) {
      model.addAttribute("name", name);
      return "hello";
   }
}

JSP 뷰

프로젝트 구조에 표시된대로 폴더  아래에 파일을 index.jsp만들고 hello.jsp파일을 만듭니다 src/main/webapp/WEB-INF/views.

index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<!-- Static content -->
<link rel="stylesheet" href="/resources/css/style.css">
<script type="text/javascript" src="/resources/js/app.js"></script>

<title>Spring Boot</title>
</head>
<body>
  <h1>Spring Boot - MVC web application example</h1>
  <hr>

  <div class="form">
    <form action="hello" method="post" onsubmit="return validate()">
      <table>
        <tr>
          <td>Enter Your name</td>
          <td><input id="name" name="name"></td>
          <td><input type="submit" value="Submit"></td>
        </tr>
      </table>
    </form>
  </div>

</body>
</html>

hello.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring Boot</title>
</head>
<body>
  <h1>Spring Boot - MVC web application example</h1>
  <hr>

  <h2>Your name is ${name}</h2>

</body>
</html>

 

Static web resources

기본적으로 봄 부팅은에서 정적 웹 콘텐츠를 제공 /static또는 /public또는 /resources또는 /META-INF/resources폴더 클래스 경로에 있습니다. 이 예제에서는 스타일 시트, 자바 스크립트 파일과 같은 모든 정적 리소스를 /static폴더에 저장합니다.

src/main/resources/static/css폴더 아래에 스타일 시트 파일을 만들고 그 안에 다음 코드를 작성하십시오.

style.css

.form {
	background-color: #efefef;
	width: 400px;
	height: 50px;
	border-radius: 7px;
	padding: 20px;
}

자, src/main/resources/static/js폴더 아래에 javascript 파일을 만들고 다음 코드를 작성하십시오.

app.js

function validate() {
	var name = document.getElementById("name").value;
	if (name == '') {
		alert('Please enter a valid name.');
		return false;
	} else {
		return true;
	}
}

Application properties

봄 부팅은에서 속성을로드하고 스프링에 application.properties추가합니다 EnvironmentSpring MVC 또는 정적 웹 컨텐트와 관련된 속성을 application.properties파일에 설정할 수 있습니다 .

원본 폴더 application.properties아래 에 파일을 src/main/resources만들고 그 안에 다음 속성을 작성합니다.

application.properties

spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
spring.mvc.static-path-pattern=/resources/**

주 - spring.mvc.static-path-pattern=/resources/** (가) 매핑됩니다 classpath:/static/css/style.css에 /resources/css/style.css마찬가지로,에 classpath:/static/js/app.js  매핑됩니다 /resources/js/app.js다음과 같이 jsp에서 이러한 정적 자원을 사용할 수 있습니다.

<link rel="stylesheet" href="/resources/css/style.css">
<script type="text/javascript" src="/resources/js/app.js"></script>

메인 클래스

Spring Boot를 사용하여 Spring MVC 애플리케이션을 부트 스트랩하려면 @SpringBootApplication 다음과 같이 annotation으로 주석이 달린 메인 클래스를 생성한다  .

MainApp.java

package com.boraji.tutorial.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MainApp {
   public static void main(String[] args) {
      SpringApplication.run(MainApp.class, args);
   }
}

 

응용 프로그램 실행

실행  MainApp.java 예 → 자바 응용 프로그램으로 실행 → 실행으로 이동 Java 응용 프로그램과 같은 클래스를

이 mvn spring-boot:run 명령을 사용하여 스프링 부팅 응용 프로그램을 실행할 수 있습니다  .

메인 클래스를 실행하면 콘솔 출력은 다음과 같이 보입니다.

이제   브라우저 주소에 http : // localhost 8080 을 입력하고 입력 필드에 사용자 이름을 입력하십시오.

 

이제   브라우저 주소에 http : // localhost 8080 을 입력하고 입력 필드에 사용자 이름을 입력하십시오.

spring-boot-mvc-jsp1.png

제출 버튼을 클릭하고 결과 페이지를보십시오.

spring-boot-mvc-jsp2.png

Spring 부트 애플리케이션을 실행 가능한 전쟁으로 패키징하기

임베디드 서블릿 컨테이너를 사용하고 있다면 jar 대신에 스프링 부트 애플리케이션을 war로 패키징해야한다. JSP 지원에는 몇 가지 제한 사항이 있습니다. 더 읽기 ..

다음 maven 명령을 사용하여 스프링 부트 응용 프로그램을 전쟁으로 패키지 할 수 있습니다.

mvn clean package

명령 줄에서 실행 가능한 전쟁 실행

다음 명령을 사용하여 CMD에서 전쟁을 실행하십시오.

>java -jar spring-boot-web-application-example-0.0.1-SNAPSHOT.war
소스 다운로드


반응형
반응형

Spring Boot Samples

The following sample applications are provided:

SampleDescription

spring-boot-sample-activemq

JMS consumer and producer using Apache ActiveMQ

spring-boot-sample-actuator

REST service with production-ready features

spring-boot-sample-actuator-log4j2

Production-ready features using log4j 2 for logging (instead of logback)

spring-boot-sample-actuator-noweb

Non-web application with production-ready features

spring-boot-sample-actuator-ui

Web UI example with production-ready features

spring-boot-sample-amqp

Message-oriented application using AMQP and RabbitMQ

spring-boot-sample-ant

Executable JAR build using Ant

spring-boot-sample-aop

Demonstrates explicit usage of Spring AOP

spring-boot-sample-atmosphere

Chat service built using Atmosphere

spring-boot-sample-batch

Define and run a Batch job in a few lines of code

spring-boot-sample-cache

Web application that uses Spring’s cache abstraction

spring-boot-sample-custom-layout

Creates custom Jar Layout

spring-boot-sample-data-cassandra

Stores data using Spring Data Cassandra

spring-boot-sample-data-couchbase

Stores data using Spring Data Couchbase

spring-boot-sample-data-elasticsearch

Stores data using Spring Data Elasticsearch

spring-boot-sample-data-jpa

Stores data using Spring Data JPA with Hibernate

spring-boot-sample-data-ldap

Stores data using Spring Data LDAP

spring-boot-sample-data-mongodb

Stores data using Spring Data MongoDB

spring-boot-sample-data-neo4j

Stores data using Spring Data Neo4j

spring-boot-sample-data-redis

Stores data using Spring Data Redis

spring-boot-sample-data-rest

RESTful service built using Spring Data REST

spring-boot-sample-data-solr

Stores data using Spring Data Solr

spring-boot-sample-devtools

Using DevTools for rapid application development

spring-boot-sample-flyway

Database migrations with Flyway

spring-boot-sample-hateoas

RESTful API built using Spring Hateoas

spring-boot-sample-integration

Integration application built using Spring Integration and its Java DSL

spring-boot-sample-jersey

RESTful service built using Jersey 2

spring-boot-sample-jersey1

RESTful service built using Jersey

spring-boot-sample-jetty

Embedded Jetty

spring-boot-sample-jetty-ssl

Embedded Jetty configured to use SSL

spring-boot-sample-jetty-jsp

Web application that uses JSP templates with Jetty

spring-boot-sample-jooq

Stores data using jOOQ

spring-boot-sample-jpa

Uses plain JPA (Hibernate)

spring-boot-sample-jta-atomikos

JTA transactions with Atomikos

spring-boot-sample-jta-bitronix

JTA transactions with Bitronix

spring-boot-sample-jta-jndi

JTA transactions using a TransactionManager and DataSource from JNDI

spring-boot-sample-jta-narayana

JTA transactions with Narayana

spring-boot-sample-junit-jupiter

Demonstrates JUnit Jupiter-based testing

spring-boot-sample-liquibase

Database migrations with Liquibase

spring-boot-sample-logback

Demonstrates Spring Boot’s custom Logback functionality configured in logback-spring.xml

spring-boot-sample-metrics-dropwizard

Demonstrates support for Dropwizard metrics

spring-boot-sample-metrics-opentsdb

Exports metrics to OpenTSDB

spring-boot-sample-metrics-redis

Exports metrics to Redis

spring-boot-sample-parent-context

Application that uses an ApplicationContext with a parent

spring-boot-sample-profile

Demonstrates some of Spring Framework’s @Profile capabilities

spring-boot-sample-property-validation

Demonstrates the usage of @ConfigurationProperties with a Spring Validator

spring-boot-sample-secure

Non-web application that uses Spring Security

spring-boot-sample-servlet

Web application with a "raw" Servlet returning plain text content

spring-boot-sample-session

Web Application that uses Spring Session to manage session data

spring-boot-sample-simple

Simple command line application

spring-boot-sample-test

Demonstrates Spring Boot’s testing capabilities

spring-boot-sample-testng

Demonstrates TestNG-based testing

spring-boot-sample-tomcat

Embedded Tomcat

spring-boot-sample-tomcat-jsp

Web application that uses JSP templates with Tomcat

spring-boot-sample-tomcat-multi-connectors

Web application that uses Tomcat configured with multiple connectors

spring-boot-sample-tomcat-ssl

Web application that uses Tomcat configured with SSL

spring-boot-sample-traditional

Traditional WAR packaging (but also executable using java -jar)

spring-boot-sample-undertow

Embedded Undertow

spring-boot-sample-undertow-ssl

Embedded Undertow configured to use SSL

spring-boot-sample-war

Web application packaged as a war file

spring-boot-sample-web-freemarker

Web application that uses FreeMarker templates

spring-boot-sample-web-groovy-templates

Web application that uses Groovy templates

spring-boot-sample-web-jsp

Web application that uses JSP templates

spring-boot-sample-web-method-security

Web application with Security configuration enabling global method security

spring-boot-sample-web-mustache

Web application that uses Mustache views

spring-boot-sample-web-secure

Web application with typical Security configuration enabling a login form

spring-boot-sample-web-secure-custom

Web application with custom Spring Security configuration

spring-boot-sample-web-secure-jdbc

Web application with Spring Security configured to use JDBC authentication

spring-boot-sample-web-static

Web application that serves static files

spring-boot-sample-web-ui

Web application with a basic UI built using Bootstrap and JQuery

spring-boot-sample-webservices

Simple contract-first SOAP web service with Spring Web Services

spring-boot-sample-websocket-jetty

WebSocket application that uses Jetty

spring-boot-sample-websocket-tomcat

WebSocket application that uses Tomcat

spring-boot-sample-websocket-undertow

WebSocket application that uses Undertow

spring-boot-sample-xml

Example show how Spring Boot can be mixed with traditional XML configuration (we generally recommend using Java @Configuration whenever possible


반응형
반응형

관련 문서

목차


이 글은 스프링 2.x 기준으로 작성되었음.

사용빈도가 높은 어노테이션 위주로 정리.

목차에 없는 항목은 API 문서를 참고할 것. 구글링하는게속편한건함정

@Component

패키지: org.springframework.stereotype

버전: spring 2.5

설정 위치: 클래스 선언부 앞

<context:component-scan> 태그를 설정파일에 추가하면 해당 어노테이션이 적용된 클래스를 빈으로 등록하게 된다. 범위는 디폴트로 singleton이며 @Scope를 사용하여 지정할 수 있다.

사용하려면 XML 설정파일에 <context:component-scan>을 정의하고 적용할 기본  패키지를 base-package 속성으로 등록한다.

context:annotation-config 태그는 어노테이션과 관련해서 다음의 BeanPostProcessor를 함께 등록 한다.

  • @Required(RequiedAnnotationBeanPostProcessor)
  • @Autowired(AutowiredAnnotationBeanPostProcessor)
  • @Resource, @PostConstruct, @PreDestory(CommonAnnotationBeanPostProcessor)
  • @Configuration(ConfigurationClassPostProcessor)
  • 그 외 Repository, Service, Controller 포함

예를 들어 다음처럼 설정하면:

<context:component-scan base-package="xxx"/>

xxx 패키지 하위에 @Component로 선언된 클래스를 bean으로 자동 등록한다. bean의 이름은 해당 클래스명(첫글자는 소문자)이 사용된다.

<context:component-scan /> 요소에는 scoped-proxy 속성이 존재 한다. scoped-proxy는 <aop:scoped-poxy/>처럼 WebApplicationContext 에서만 유효하며 "session", "globalSession", "request" 이외의 scope는 무시 되며 아래의 3가지 값을 설정 할 수 있다.

  • no: proxy를 생성하지 않는다.(기본값)
  • interfaces: JDK Dynamic Proxy를 이용한 Proxy 생성
  • targetClass: 클래스에 대해 프록시를 생성(CGLIB를 이용한 Proxy 생성)
@Component
@Scope("prototype")   // 생략하면 싱글톤
public class Test {
       .....
}

CGLIB

기존의 자바 클래스파일로부터 자바의 소스코드를 동적으로 생성하는 라이브러리(자바 소스 변경)

http://sourceforge.net/projects/cglib/

스캔 대상 클래스 범위 지정하기

<context:include-filter> 태그와 <context:exclude-filter> 태그를 사용하면 자동 스캔 대상에 포함시킬 클래스와 포함시키지 않을 클래스를 구체적으로 명시할 수 있다.

<context:component-scan base-package="spring.demo" scoped-proxy="no">
   <context:include-filter type="regex" expression="*HibernateRepository"/>
   <context:exclude-filter type="aspectj" expression="..*IBatisRepository"/>
</context:component-scan>

위와 같이 <context:include-filter> 태그와 <context:exclude-filter> 태그는 각각 type 속성과 expresseion 속성을 갖는데, type 속성에 따라 expression 속성에 올 수 있는 값이 달라진다. type 속성에 입력가능한 값은 다음과 같다:

  • annotation: 클랙스에 지정한 어노테이션이 적용됐는지의 여부. expression 속성에서는 "org.example.SomeAnnotation"와 같은 어노테이션 이름을 입력한다.
  • assignable: 클래스가 지정한 타입으로 할당 가능한지의 여부.  expression 속성에는 "org.exampleSomeClass" 와 같은 타입 이름을 입력한다.
  • regex: 클래스 이름이 정규 표현식에 매칭되는 지의 여부.  expression 속성에는 "org\.example\.Default.*" 와 같이 정규표현식을 입력한다.
  • aspectj: 클래스 이름이 AspectJ 의 표현식에 매칭되는 지의 여부.  expression 속성에는 "org.example..*Service+" 와 같이 AspectJ 의 표현식을 입력한다.

@Required

패키지: org.springframework.beans.factory.annotation

버전: spring 2.0

설정 위치: setter 메서드 앞

Required 어노테이션은 필수 프로퍼티임을 명시하는 것으로 필수 프로퍼티를 설정하지 않을 경우 빈 생성시 예외를 발생시킨다.

import org.springframework.beans.factory.annotation.Required

public class TestBean {
    @Required
    private TestDao testDao;

    public void setTestDao(TestDao testDao) {
        this.testDao = testDao;
    }
}
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanpostProcessor"/>
<bean name="testBean"  class="han.test.TestBean">
    <property name="testDao" ref="testDao"/>
    <!-- @Required 어노테이션을 적용하였으므로 설정하지 않으면 예외를 발생시킨다. -->
</bean>

RequiredAnnotationBeanPostProcessor 클래스는 스프링 컨테이너에 등록된 bean 객체를 조사하여 @Required 어노테이션으로 설정되어 있는 프로퍼티의 값이 설정되어 있는지 검사한다.

사용하려면 <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 하지만 이를 대신하여 <context:annotation-config> 태그를 사용해도 된다:

<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    <context:annotation-config/>
</beans>

@Autowired

패키지: org.springframework.beans.factory.annotation

버전: spring 2.5

설정 위치: 생성자, 필드, 메서드(setter메서드가 아니여도 된다) 앞

의존관계를 자동설정할 때 사용하며 타입을 이용하여 의존하는 객체를 삽입해 준다. 그러므로 해당 타입의 빈객체가 존재하지 않거나 또는 2개 이상 존재할 경우 스프링은 예외를 발생시키게 된다.

options:

  • required: Autowired 어노테이션을 적용한 프로퍼티 중 반드시 설정할 필요가 없는 경우에 false값을 주어 프로퍼티가 존재하지 않더라도 스프링이 예외를 발생하지 않도록 한다. 기본값은 TRUE. ex) @Autowired(required=false)

사용하려면 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.

@Autowired를 적용할 때 같은 타입의 빈이 2개 이상 존재하게 되면 예외가 발생하는데, Autowired도 이러한 문제가 발생한다. 이럴 때 @Qualifier를 사용하면 동일한 타입의 빈 중 특정 빈을 사용하도록 하여 문제를 해결할 수 있다.

@Autowired
@Qualifier("test")
private Test test;

@Qualifier

패키지: org.springframework.beans.factory.annotation

버전: spring 2.5

설정 위치: @Autowired 어노테이션과 함께 사용된다.

qualifier 어노테이션은 @Autowired의 목적에서 동일 타입의 빈객체가 존재시 특정빈을 삽입할 수 있게 설정한다. @Qualifier("mainBean")의 형태로 @Autowired와 같이 사용하며 해당 <bean>태그에 <qualifire value="mainBean" /> 태그를 선언해주어야 한다. 메서드에서 두개이상의 파라미터를 사용할 경우는 파라미터 앞에 선언해야한다.

options:

  • name: alias명

사용하려면 동일타입의 빈객체 설정에서 <qualifier value="[alias명]" />를 추가해 준다.

<bean id="user2" class="com.sp4.UserImpl">
    <property name="name" value="스프링"/>
    <property name="age" value="20"/>
    <property name="tel" value="000-0000-0000"/>
</bean>

<bean id="userService1" class="com.sp4.UserService"/>
public class UserService {
    @Autowired
    @Qualifier("user2")
    private User user;

    public String result() {
        return user.getData();
    }
}

@Resource

자바 6 및 JEE5에 추가된 것으로 어플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용 한다. 스프링 2.5 부터 지원하는 어노테이션으로 스프링에서는 의존하는 빈 객체를 전달할 때 사용한다.

@Autowired와 흡사하지만 @Autowired는 타입으로(by type), @Resource는 이름으로(by name)으로 연결한다는 점이 다르다.

options:

  • name: 자동으로 연결될 빈객체의 이름을 입력한다. ex) @Resource(name="testDao")

사용하려면 <bean class="org.springframework.beans.factory.annotation.CommonAnnotationBeanPostProcessor"/> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.

<beans>
    <!-- 기타 설정 생략 -->
    <context:annotation-config/>

    <bean id="user2" class="com.test.UserImpl" p:data="65536"/>
</beans>
public class UserService {
    @Resource(name="user2")
    private User user;
    //UserImpl user2 = new UserImpl();
    //User user = user2;

    public void setUser(User user) {
        this.user = user;
    }
    public String result() {
        return user.getData();
    }
}

@Scope

패키지: org.springframework.beans.factory.annotation

설정: prototype, singleton, request, session, globalSession

스프링은 기본적으로 빈의 범위를 "singleton" 으로 설정한다. "singleton" 이 아닌 다른범위를 지정하고 싶다면 @Scope 어노테이션을 이용하여 범위를 지정한다.

@Component
@Scope(value="prototype")
public class Worker {}
@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class Worker {}

@PostConstruct

패키지: javax.annotation

버전: jdk1.6, spring 2.5

설정 위치: 초기화 작업 수행 메서드 앞

의존하는 객체를 설정한 이후에 초기화 작업을 수행하기 위해 사용한다. 스프링에 의해 인스턴스가 생성된 후 어노테이션이 적용된 메서드가 호출된다. 사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.

@PostConstruct
public void init() {
    System.out.println("객체 생성 후 내가 먼저 실행된다.");
}

@PreDestroy

패키지: javax.annotation

버전: jdk1.6, spring 2.5

설정 위치: 해당 작업 메서드 앞

컨테이너에서 객체를 제거하기 전에 해야할 작업을 수행하기 위해 사용한다.

사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.

@Inject

SR-330 표준 Annotation으로 Spring 3 부터 지원하는 Annotation이다. 특정 Framework에 종속되지 않은 어플리케이션을 구성하기 위해서는 @Inject를 사용할 것을 권장한다. @Inject를 사용하기 위해서는 클래스 패스 내에 JSR-330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가되어야 함에 유의해야 한다. 

@Service

@Service를 적용한 Class는 비지니스 로직이 들어가는 Service로 등록이 된다. Controller에 있는 @Autowired는 @Service("xxxService")에 등록된 xxxService와 변수명이 같아야 하며 Service에 있는 @Autowired는 @Repository("xxxDao")에 등록된 xxDao와 변수명이 같아야 한다.

@Service("helloService")
public class HelloServiceImpl implements HelloService {
    @Autowired
    private HelloDao helloDao;

    public void hello() {
        System.out.println("HelloServiceImpl :: hello()");
        helloDao.selectHello();
    }
}

helloDao.selectHello(); 와 같이 @Autowired를 이용한 객체를 이용하여 Dao 객체를 호출한다:

@Service("test2.testService")
//괄호 속 문자열은 식별자를 의미한다.
//괄호를 생략할 경우 클래스명 그대로 사용한다.
//따라서 ,같은 클래스명이 존재 할 시 같은 식별자가 생성되기때문에 에러가 발생한다.
public class TestService {
    public String result(int num1, int num2, String oper) {
        String str = null;

        if (oper.equals("+")) {
            //...
            return str;
        }
    }
}

@Resouce로 연결

@Resource(name="test2.testService")
//name에 필요한 것은 @Service("test2.testService") <- 여기서 괄호 속 문자열, 즉 식별자

private TestService service;
//TestService service = new TestService(); 라고 하는것과 같은 식

@RequestMapping(value="/test2/oper.action", method={RequestMethod.GET})
public String form() throws Exception {
    return "test2/write";
}

@Repository

패키지: org.springframework.stereotype

버전: spring 2.0

@Repository는 일반적으로 DAO에 사용되며 DB Exception을 DataAccessException으로 변환한다.

@Repository("bbs.boardDAO")
public class BoardDAO {
    private SqlSession sqlSession;

    public int insertBoard(Board dto) throws Exception {
        ...
    }
}
public class BoardServiceImpl implements BoardService {
    @Resource(name="bbs.boardDAO")
    private BoardDAO dao;

    public int insertBoard(Board dto){}
}

@Controller

http://noritersand.tistory.com/474

@RequestMapping

http://noritersand.tistory.com/475

@RequestParam

http://noritersand.tistory.com/357

@SessionAttributes

SessionAttribute annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용한다.

@Controller
@SessionAttributes("blog")
public class BlogController {
    // 중간생략

    @RequestMapping("/createBlog")
    public ModelMap createBlogHandler() {
        blog = new Blog();
        blog.setRegDate(new Date());
        return new ModelMap(blog);
    }

    // 중간생략
}

@SessionAttributes는 model로 할당된 객체 중 지정된 이름과 일치하는 객체를 세션 속성에도 추가한다.

@SessionAttributes("someSessionAttr")
class ExampleController2 {
	@RequestMapping("/test")
	public ModelAndView drawTest(ModelAndView view, @ModelAttribute("someSessionAttr") String someSessionAttr) {
		view.addObject("someSessionAttr", someSessionAttr);
		return view;
	}
}

@RequestBody

@RequestBody 어노테이션이 적용된 파라미터는 HTTP Request body의 내용이 전달된다.

참고: http://java.ihoney.pe.kr/283

@RequestMapping(value="/test")
public void penaltyInfoDtlUpdate(@RequestBody String body,
        HttpServletRequest req, HttpServletResponse res,
        Model model, HttpSession session) throws Exception  {

    System.out.println(body);
}

@ResponseBody

참고: http://ismydream.tistory.com/140

클라이언트에 JSON 형식의 값을 응답할 때 유용하다. 메서드에 @ResponseBody를 적용한 후 문자열을 리턴하면 그 값은 HTTP response header가 아니라 HTTP response body에 쓰여진다. 객체를 넘길경우 스프링에 내장된 JACKSON에 의해 문자열로 변환될 것이다.

또한 @ResponseBody가 적용된 컨트롤러는 context에 설정된 resolver를 무시한다.

@RequestMapping("/getVocTypeList")
@ResponseBody
public ArrayList<Object> getVocTypeList() throws Exception {
    HashMap<String, Object> vocData = gvocInf.searchVocTypeList();
    return (ArrayList<Object>) vocData.get("data");
}

@PathVariable

URL의 일부를 파라미터 혹은 변수로 사용한다.

package com.sp.ex;

@Controller("ex.exController")
public class ExController{
    @RequestMapping(value="/blog/{userId}/main.action", method=RequestMethod.GET)
    public String main(HttpServletRequest req
                       , @PathVariable String userId) throws Exception    {

        req.setAttribute("userId", userId);
        return "restful/result";
    }
}



출처 : http://noritersand.tistory.com/156


반응형
반응형

Spring Web MVC의 @Controller 클래스에서 클래스 레벨에 명시 가능한 어노테이션은 아래와 같다.


  • @ResponseBody: 모든 메써드의 리턴 오브젝트를 적절한 형태로 변환 후 HTTP 응답 메시지의 바디에 담아 반환한다. (오브젝트에서 바디로의 실제 변환은 HttpMessageConverter 인터페이스의 각 구현 클래스들이 수행한다. 예를 들면 String 리턴 타입은 StringHttpMessageConverter가 변환을 담당한다.) 클래스 레벨에 명시하면 View로의 반환을 완전히 배제하기 때문에 REST API 구현시 적합하다.


  • @RestController@Controller에 위에 설명한 @ResponseBody를 추가한 효과를 가진다. REST API 구현을 염두한 축약형 어노테이션이다.


  • @RequestMapping: 응답을 수행할 HTTP 요청을 명시할 수 있다.

    • path (StringString[]): 요청 URI를 명시한다. 배열을 통한 복수개의 요청 URI를 지정할 수 있다. 클래스 레벨에 명시한 값은 모든 메써드 레벨에 명시한 path 값 앞에 붙어 접두어 역할을 한다.
@RequestMapping("/v1/players")
  • @PropertySource: 프라퍼티 소스를 명시할 수 있다. 필드 레벨에서 @Value 등을 통해 클래스 레벨에서 명시한 프라퍼티 소스의 값을 주입할 수 있다.
// ROOT CLASSPATH(/src/main/java/resources)에 위치한 some.properties를 프라퍼티 소스로 명시한다.
@PropertySource("classpath:/some.properties")

클래스 필드 레벨

필드 레벨에 명시 가능한 어노테이션은 아래와 같다.


  • @Autowired: 적합한 이름의 스프링 빈을 자동으로 주입한다. 명백하게 1개의 스프링 빈만 존재할 경우 사용한다.


  • @Resource: 지정한 이름의 스프링 빈을 주입한다. 같은 타입의 스프링 빈이 2개 이상 존재할 경우 사용한다.

    • name (String): 주입할 스프링 빈의 이름이다.

  • @Value: 시스템 환경 변수, Java 환경 변수, Spring 환경 변수, 프라퍼티 리소스 상수 등의 값을 주입한다.


메써드 레벨

  • @RequestMapping: 메써드가 어떤 HTTP 요청을 처리할 것인가를 작성한다. 구체적인 작성 예는 아래와 같다.

@RequestMapping(
  /**
   * HTTP URI가 "/users"인 것만 처리한다. 만약 앞서 클래스 레벨에서 "/v1"이 명시되었다면 "/v1/users"를 처리하게 된다.
   */
  path = "/users",

  /**
   * HTTP 요청 메써드가 "POST"인 것만 처리한다.
   */
  method = RequestMethod.POST,

  /**
   * HTTP 요청 헤더가 "Content-Type: application/json;charset=UTF-8"인 것만 처리한다.
   * 다른 값이 들어올 경우 org.springframework.web.HttpMediaTypeNotSupportedException을 발생시킨다.
   * HTTP 요청 헤더에 명시된 Content-Type은 HTTP 요청 바디의 형식을 의미한다. 즉, 서버에서는 JSON 형식의 바디만 처리하겠다는 의미이다.
   * 참고로 GET 요청은 바디를 가지지 않으므로 아래 파라메터를 명시할 필요가 없다.
   */
  consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,

  /**
   * HTTP 응답 헤더로 "Content-Type: application/json;charset=UTF-8"을 반환한다.
   * 생략할 경우 메써드 리턴 타입에 따라 Content-Type을 자동으로 판단하여 반환한다.
   */
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)

메써드 아규먼트 레벨

  • 특정 어노테이션 없이 POJO 클래스를 아규먼트로 명시하면 HTTP 요청 메시지의 QueryString 문자열을 변환하여 저장한다.

  • @ValidJSR-303 (Bean Validation) 스펙에 명시된 어노테이션으로 요청 파라메터에 대한 유효성 검사가 가능하다. 유효성 검사 실패시 org.springframework.validation.BindException이 발생한다. 대상 아규먼트는 기본 타입 및 POJO 타입 모두 가능하다.

  • @RequestBodyHTTP 요청 메시지의 BODY를 변환하여 담을 아규먼트 앞에 명시한다. HTTP 스펙에 따라 GET 이외의 메써드에서만 명시 가능하다. (무시하고 명시할 경우 org.springframework.http.converter.HttpMessageNotReadableException이 발생한다.) 한편 앞서 설명한 @Valid를 추가로 명시할 수 있다. 유효성 검사 실패시 org.springframework.web.bind.MethodArgumentNotValidException을 발생시킨다.



출처: http://jsonobject.tistory.com/257 [지단로보트의 블로그]

반응형
반응형

<plugin>

    <groupId>org.apache.maven.plugins</groupId>

    <artifactId>maven-javadoc-plugin</artifactId>

    <version>2.9.1</version>

</plugin> 


이렇게 쓴 후 프로젝트를 오른쪽 클릭 > Run As > Maven build를 클릭하게 됩니다.


클릭하면, 아래와같이 Run Configurations 이 보여지게 되고 여기 내용에서 Goals: 이라는 설정 칸에 다음과 같이 작성을 합니다 "javadoc:javadoc"



그런 후 Run을 하게되면 maven 프로젝트의 target > site > apidocs 안에 웹페이지 형태로 자바문서가 만들어지게 됩니다 ^^






이걸 원하는 곳에 본사하여 index.html을 웹브라우저로 실행하게되면 자신이 만든 자바 프로젝트의 패키지, 클래스, 멤버 함수들을 문서로 확인할 수 있게 되겠습니다~



출처: http://intruder.tistory.com/117 [I.K.Picture & IT Info.]

반응형
반응형

오늘은 바로 "이클립스 한글화"에 대한 글입니다.

다들 이클립스를 영어로 쓰시길래

나 : 한글패치 안해?
친구 : 그런게 있어?

네. 그런게 있습니다.

바로 "Babel"이라는 이름으로 진행되고 있는 프로젝트입니다.

[Eclipse Babel Project : 다운로드]

위의 사이트로 들어가시면

자신에게 맞는 버전을 선택합니다.

선택을 하고

Korean을 선택합니다.

그리고 eclipse-ko를 선택합니다.

1MB정도밖에 안되기 때문에 그냥 일본서버에서 다운받습니다.

압축을 풀면

두개의 폴더가 나오게 되는데 이걸 이클립스가 설치된 폴더에 그대로
덮어씌우면 끝!!!
따로 설정할것도 없습니다.

덮어씌우고 이클립스를 실행시키면?!

한글화 완성!!

아직 80퍼센트정도 번역이기에 전체가 번역되어 있지는 않지만

주 기능들은 전부 번역되어 있습니다.



출처 : https://m.blog.naver.com/PostView.nhn?blogId=skyvvv624&logNo=220727945231&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F

반응형
반응형



1. 의존성 추가

<dependency>

    <groupId>org.springframework.integration</groupId>

    <artifactId>spring-integration-sftp</artifactId>

    <version>4.3.4.RELEASE</version>

</dependency>


2. 최종 디렉토리 구조


spring-integration sftp download example


3. Java 구성을 사용하는 SftpConfig

DefaultSftpSessionFactory호스트, IP 포트, 사용자 이름 및 암호 (또는 암호문이있는 개인 키) 등 모든 필수 매개 변수로 SFTP 세션 팩토리 ( 를 구성 해야합니다. 동일한 구성이 SFTP 업로드 예제 에서 이미 사용되었습니다 .

그런 다음 MessageSource<File>빈 을 만들어서 이것을 @로 정의해야합니다. InboundChannelAdapter. 이 구성 요소는 새 파일의 존재 여부를 원격 SFTP 서버에서 정기적으로 확인합니다. 정규 기간 주석 정의 @Poller의 정의 내 InboundChannelAdapterPoller크론 식으로 정의된다).

그런 다음 우리 는 동기화 메커니즘의 전략을 정의하는 SftpInboundFileSynchronizer by 의 인스턴스를 만들 필요가 있습니다. @InboundChannelAdapter)즉, 원격 파일 이름 필터 ( sftpRemoteDirectoryDownloadFilter), 원격 디렉토리 경로 ( sftpRemoteDirectoryDownload) 또는 원격 파일이 있어야하는지 여부 를 설정할 수 있습니다. 전송이 완료되면 삭제됩니다.

마지막으로 중요한 bean은 들어오는 파일을 처리 MessageHandler 하는 데 사용되는 일반 bean 과 관련이 @ServiceActivator. The MessageHandler 있습니다.


01
02
03
04
05
06
07
08
09
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@Configuration
public class SftpConfig {
 
    @Value("${sftp.host}")
    private String sftpHost;
 
    @Value("${sftp.port:22}")
    private int sftpPort;
 
    @Value("${sftp.user}")
    private String sftpUser;
 
    @Value("${sftp.privateKey:#{null}}")
    private Resource sftpPrivateKey;
 
    @Value("${sftp.privateKeyPassphrase:}")
    private String sftpPrivateKeyPassphrase;
 
    @Value("${sftp.password:#{null}}")
    private String sftpPasword;
 
    @Value("${sftp.remote.directory.download:/}")
    private String sftpRemoteDirectoryDownload;
 
    @Value("${sftp.local.directory.download:${java.io.tmpdir}/localDownload}")
    private String sftpLocalDirectoryDownload;
 
    @Value("${sftp.remote.directory.download.filter:*.*}")
    private String sftpRemoteDirectoryDownloadFilter;
 
    @Bean
    public SessionFactory<LsEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost(sftpHost);
        factory.setPort(sftpPort);
        factory.setUser(sftpUser);
        if (sftpPrivateKey != null) {
            factory.setPrivateKey(sftpPrivateKey);
            factory.setPrivateKeyPassphrase(sftpPrivateKeyPassphrase);
        else {
            factory.setPassword(sftpPasword);
        }
        factory.setAllowUnknownKeys(true);
        return new CachingSessionFactory<LsEntry>(factory);
    }
 
    @Bean
    public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
        SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(true);
        fileSynchronizer.setRemoteDirectory(sftpRemoteDirectoryDownload);
        fileSynchronizer
                .setFilter(new SftpSimplePatternFileListFilter(sftpRemoteDirectoryDownloadFilter));
        return fileSynchronizer;
    }
 
    @Bean
    @InboundChannelAdapter(channel = "fromSftpChannel", poller = @Poller(cron = "0/5 * * * * *"))
    public MessageSource<File> sftpMessageSource() {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                sftpInboundFileSynchronizer());
        source.setLocalDirectory(new File(sftpLocalDirectoryDownload));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        return source;
    }
 
    @Bean
    @ServiceActivator(inputChannel = "fromSftpChannel")
    public MessageHandler resultFileHandler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                System.err.println(message.getPayload());
            }
        };
    }
}

3. 스프링 통합을 통한 스프링 부트 설정

필자는 예제에서 Spring Boot를 사용 했으므로 주석 @SpringBootApplication이 분명합니다. 더 재미있는 주석이다 @IntegrationComponentScan그리고 @EnableIntegration이는 이전 구성 파일에 사용 된 모든 다른 구성을 가능하게 할 것이다.

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@IntegrationComponentScan
@EnableIntegration
public class SpringSftpDownloadDemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringSftpDownloadDemoApplication.class, args);
    }
}

4. 사용 예

여기에서 기본적인 사용 사례를 볼 수 있습니다. 공개 키 인증을 사용하는 실제 SFTP 서버 (예 : 암호없이)를 사용하여 통합 테스트를 만들었습니다. 
이 테스트는 비동기 스레드를 시작하여 다운로드 한 파일의 존재를 확인합니다.

01
02
03
04
05
06
07
08
09
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
36
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = { "sftp.port = 10022""sftp.remote.directory.download.filter=*.xxx"})
public class SpringSftpDownloadDemoApplicationTests {
 
    private static EmbeddedSftpServer server;
 
    private static Path sftpFolder;
 
    @Value("${sftp.local.directory.download}")
    private String localDirectoryDownload;
 
 
    @BeforeClass
    public static void startServer() throws Exception {
        server = new EmbeddedSftpServer();
        server.setPort(10022);
        sftpFolder = Files.createTempDirectory("SFTP_DOWNLOAD_TEST");
        server.afterPropertiesSet();
        server.setHomeFolder(sftpFolder);
        // Starting SFTP
        if (!server.isRunning()) {
            server.start();
        }
    }
 
    @Before
    @After
    public void clean() throws IOException {
        Files.walk(Paths.get(localDirectoryDownload)).filter(Files::isRegularFile).map(Path::toFile)
                .forEach(File::delete);
    }
 
    @Test
    public void testDownload() throws IOException, InterruptedException, ExecutionException, TimeoutException {
        // Prepare phase
        Path tempFile = Files.createTempFile(sftpFolder, "TEST_DOWNLOAD_"".xxx");
 
        // Run async task to wait for expected files to be downloaded to a file
        // system from a remote SFTP server
        Future<Boolean> future = Executors.newSingleThreadExecutor().submit(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                Path expectedFile = Paths.get(localDirectoryDownload).resolve(tempFile.getFileName());
                while (!Files.exists(expectedFile)) {
                    Thread.sleep(200);
                }
                return true;
            }
        });
 
        // Validation phase
        assertTrue(future.get(10, TimeUnit.SECONDS));
        assertTrue(Files.notExists(tempFile));
    }
 
    @AfterClass
    public static void stopServer() {
        if (server.isRunning()) {
            server.stop();
        }
    }
}


etc

1. 단지 파일업로드만 구현하려면 @Test 안에 있는 소스를 이용한다.

2. 파일업로드 구성하려면 sftpconfig.java에서 인증부분을 지워야함.

3. 예제 소스 git 주소 : https://github.com/pajikos/java-examples/tree/master/spring-sftp-download-demo


출처 : https://blog.pavelsklenar.com/spring-integration-sftp-download/



반응형
반응형

com.jcraft.jsch.JSchException: java.io.IOException: Pipe closed

        at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:242)

        at com.jcraft.jsch.Channel.connect(Channel.java:200)

        at com.jcraft.jsch.Channel.connect(Channel.java:144)

        at net.ib.paperless.common.SFTPHandler.init(SFTPHandler.java:61)

        at net.ib.paperless.service.AttachService.putFileUpload(AttachService.java:275)

        at net.ib.paperless.service.AttachService.eFormAttachFileSave(AttachService.java:72)

        at net.ib.paperless.controller.AttachFileController.attachFile(AttachFileController.java:68)

        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

        at java.lang.reflect.Method.invoke(Method.java:498)

        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)

        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)

        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)

        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)

        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)

        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)

        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)

        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)

        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)

        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)

        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)

        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)

        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)

        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)

        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

        at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:117)

        at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:61)

        at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:92)

        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

        at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:110)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

Caused by: java.io.IOException: Pipe closed

        at java.io.PipedInputStream.read(PipedInputStream.java:307)

        at java.io.PipedInputStream.read(PipedInputStream.java:377)

        at com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2325)

        at com.jcraft.jsch.ChannelSftp.header(ChannelSftp.java:2351)

        at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:211)







확인해야 할것.

1. jsch 라이브러리 버전을 최신버전인 0.1.54를 사용했었는데.. 0.1.42 버전으로 낮춰서 사용

2. sftp 접속 정보를 정확히 확인해봐야함

etc. 필자는 spring-boot를 사용하는데, properties가 개발용하고 상용이 있어 톰캣에서 올릴때 뭔가 꼬여서 올라가 났던 에러로 추정

3. /etc/ssh/sshd_config 에서 경로 확인 및 틀리다면 수정
# override default of no subsystems 
Subsystem sftp /usr/libexec/openssh/sftp-server


반응형

'JAVA/SPRING > JAVA' 카테고리의 다른 글

Maven으로 javadoc API 문서 만들기  (0) 2017.12.04
Eclipse 한글화  (0) 2017.12.01
[logback] 로그백 로그파일 롤링 커스터마이징  (0) 2017.11.29
SFTP 사용방법 (jsch 라이브러리 사용)  (1) 2017.11.29
OOP 개념  (0) 2017.11.28

+ Recent posts