Jar 파일에 JSP 파일 넣는 방법

이 방법은 servlet 3.0 을 지원하는 WAS에서만 가능한 방법입니다.

웹 관련 라이브러리를 만들다보면, UI(HTML, JSP, Javascript, css 등) 파일을 함께 배포하고 싶을 때가 있습니다. 즉, 비밀번호 등록 기능 뿐 아니라, 비밀번호 등록 화면까지도 라이브러리에 넣고 싶은 경우가 일 예가 되겠습니다.

그런데, Java 라이브러리는 Jar파일로 만들어야 할 터인데, 화면은 보통 JSP로 만들고…
이것을 어떻게 배포해야 할까요?

META-INF folder를 이용하면 됩니다.
META-INF folder 밑에 resources라는 folder를 만들고, 그 밑에 css, javascript, jsp, html 등을 넣어 jar로 묶어 배포하면 됩니다.
jar 파일의 META-INF/resources folder는  web root로 인식되도록 약속되어 있기 때문입니다.

예를 들어, mylib.jar 파일 안에 “META-INF/resources/jsp/main.jsp”라는 파일이 있다면, 브라우저에서
http://xxxxx.com/jsp/main.jsp ” 라고 입력하면, 브라우저에 jsp 파일 내용이 출력됩니다.
그런데, 요즘에는 Spring을 사용하면서, jsp 파일이 직접 호출되는 것을 막기 위해 “WEB-INF” 밑에 두고 템플릿 엔진을 사용하는 것이 일반화 되었죠. 이것 역시 아래와 같이 jar 파일을 구성하면, jsp 파일을 브라우저에서 직접 호출할 수 없게 됩니다.
<jar 파일>/META-INF/resources/WEB-INF/jsp/main.jsp

정리하자면, jar 파일안에 있는 “META-INF/resources”는 이 파일을 라이브러리로 사용하는 Web project의 web root와 동일하게 인식한다는 것입니다.

Spring4 ) #1: Hello World

사전 준비 사항: 아래 글을 읽었거나, 준비가 된 상태.

(준비) Gradle 설치하기 – Spring4
(준비) STS 및 Gradle Support plugin 설치

STS와 Spring4를 이용해 console에 “Hello World”라고 출력하는 간단한 프로그램을 만들어 보자. 이번에는 STS의 도움을 받지 않고, 수작업으로 해 보도록 하겠다. 처음 부터 자동으로 하게 되면, 뭐가 어찌 어찌 된 건지 알기 어렵기 때문이다.

1. Project 생성

“File > New > Other”를 클릭한다.

demo1

“General – Project”를 선택하고 (Next) click

demo2

Project name에 “demo1″이라고 입력하고, (Finish) 버튼 click한다. 그러면, 아래와 같이 일반 프로젝트가 텅빈 상태로 생성된다.

demo1-1

이제, 프로젝트 위에 마우스를 올려 놓고, 오른 마우스를 click하여 팝업메뉴가 나타나면, “New > Configure > Convert to Gradle Project” 를 클릭한다. 그러면, Console에 “BUILD SUCCESSFUL”이라는 메시지가 나타나고, 프로젝트 아이콘이 “G”가 붙은 폴더 아이콘으로 변경될 것이다.

demo1-3

2. 코드 작성

이제 코드를 작성해 보자. 먼저 demo1 Project를 선택하고, 오른 마우스를 클릭하여 나타나는 팝업 메뉴에서 “Property” 메뉴를 선택하자.

demo1-4

위와 같은 화면이 나타날 것이며, 왼쪽 리스트에서 “Java Build path”를 선택하여 나타난 오늘쪽 화면에서 “Source” tab를 선택하고, 다시 (Add folder) 버튼을 클릭한다. 새로운 팝업화면이 나타나고, 입력박스에 “src/main/java”를 입력한 후 (Finish) 버튼을 클릭한다. 그러면, 아래와 같은 화면으로 바뀔 것이다.

demo1-6

이번에는 gradle의 설정 파일인 build.gradle을 project folder에 아래와 같이 생성한다.

demo1-1

apply plugin: 'application'
mainClassName = 'demo.Application'
repositories {
	mavenCentral()
}
dependencies {
	compile("org.springframework:spring-context:4.1.2.RELEASE")
}

이 설정을 잠깐 살펴보면,
mainClassName이 ‘demo.Application’으로 되어 있으니, gradle로 실행을 하면, demo package의 Application이라는 class가 실행될 것이다.(아직 작성하지 않았다)

repositories에 mavenCentral()이 적혀 있으니, maven의 공식 repository를 사용한다는 뜻이고,

dependencies에 compile(‘org.springframework:spring-context:4.1.2.RELEASE’)라고 적혀 있으니, maven으로 보자면, 아래 모듈이 포함될 것이다.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.2.RELEASE</version>
</dependency>

build.gradle의 변경 정보를 반영하기 위해, demo 프로젝트를 선택하고, 오른 마우스를 클릭하여 나타난 팝업메뉴에서 “Gradle > Refresh Dependencies” 메뉴를 클릭한다. 그러면, 아래와 같이 바뀔 것이다.

demo1-1

Maven project에서와 유사한 화면이다.  이제, 코드를 작성할 차례다. “src/main/java” folder에 demo라는 package를 만들고 아래와 같이 3개의 파일을 작성하자.

demo1-2

MessageService.java

package demo;

public interface MessageService {
	public String getMessage();
}

HelloWorldMessage.java

package demo;

public class HelloWorldMessage implements MessageService {
	public String getMessage() {
		return "Hello World";
	}
}

Application.java

package demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

public class Application {

	@Bean
	MessageService helloWorldMessageService() {
		return new HelloWorldMessage();
	}
	
	public static void main(String[] args) {
		ApplicationContext context = 
			new AnnotationConfigApplicationContext(Application.class);
		MessageService service = context.getBean(MessageService.class);
		System.out.println(service.getMessage());
	}
}

파일들의 관계를 살펴보면, 이렇다.
MessageService.java는 interface이고, 이를 구현한 구현체는 HelloWorldMessage.java이다. 여기까지는 그 동안 보아왔던 일반적인 구조다. Application.java를 살펴보자. 눈에 띄는 것은 “@Bean”. 이것은 그동안 Spring XML 설정에서 작성해 왔던 <bean>과 같은 기능을 하는 Annotation이다. 이 덕분에, 아래 코드가 MessageService 대신, HelloWorldMessage class를 사용하게 된다.

MessageService service = context.getBean(MessageService.class);

context.getBean()에 넘겨진 MessageService.class를, spring은 구현체를 return하려고 하는데, return type이 MessageService인 설정(@Bean)을 찾아서 있으면 그것을 return하게 되는 것이다. @Bean의 영향은 잠시 뒤에 알아보도록 하자.

이제, 실행을 해볼 차례다.
demo 프로젝트를 마우스로 선택하고, 오른 마우스 버튼을 클릭 하여 나타나는 팝업 메뉴에서 “Run as > Gradle build” 메뉴를 클릭하면, 아래 화면이 나타난다. 다만, 앞으로 하게될 설정을 하고, 실행을 하게 되면, 이 화면은 나타나지 않는다. 다시 나타나게 하려면, “Run as > Gradle build…”를 선택하면 된다.

demo1-3

위 화면에 “run”을 입력하고 (Run) 버튼을 클릭하면, 실행이 된다. 결과는 console화면에서 확인할 수 있다. 아래와 같은 결과를 볼 수 있다면, 정상적으로 실행된 것이다.

[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      run
[sts] -----------------------------------------------------
:compileJava
:processResources UP-TO-DATE
:classes
:run11월 22, 2014 12:49:18 오전 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5e9f23b4: startup date [Sat Nov 22 00:49:18 KST 2014]; root of context hierarchy

Hello World

BUILD SUCCESSFUL

Total time: 0.567 secs
[sts] -----------------------------------------------------
[sts] Build finished succesfully!
[sts] Time taken: 0 min, 0 sec
[sts] -----------------------------------------------------

이제, @Bean의 역할을 체험할 차례다. Application.java에서 “@Bean”을 삭제하고 실행해 보라. 아래와 같은 어마무시한 에러 문자를 확인할 수 있을 것이다.

demo1-5

끝~

(준비) STS 및 Gradle Support plugin 설치

STS 설치하기

Spring Framework으로 개발한다고 하면, 그냥 Eclipse 보다는 spring.io에서 배포하고 있는 STS(Spring Tool Suite)를 사용하는 것이 좋겠다. Spring을 위한 Project 생성을 별도로 제공하고 있기 때문이다.

STS는 아래 사이트에서 다운로드 받아 압축만 풀면 끝이다. 쉽다.

http://spring.io/tools/sts

STS

Gradle Support plugin 설치하기

앞서, Gradle에 대해 간략하게 알아보았다(Gradle 설치하기 – Spring4). 이번에는 STS(Spring Tool Suite)에 Gradle support plugin을 설치하도록 하자. 재밌게도, Spring core는 gradle로 build를 하고 있다고 하는데, 정작 STS(3.6.2.RELEASE)에는 maven이 기본 설치되어 있는 반면에 gradle은 설치되어 있지 않다.

그러나, 역시 설치는 쉽다. STS를 실행하면 나타나는 Dashboard 화면을 보자. 닫아 버렸다면, 아래 메뉴를 클릭해서 다시 열 수 있다.

Help > Dashboard

gradle-1

위 Dashboard 화면에서 “IDE EXTENSIONS”를 click한다. 그러면 아래 하면이 나타날 것이다.

gradle-2

위 화면에서 “Gradle Support”를 선택하고 (Install) 버튼을 클릭한다. 그러면, 아래와 같이 다른 Plugin 설치하는 것과 동일한 화면이 나타난다.

gradle-3

주의할 것은 위 화면이 처음 나타날 때, 목록에 아무것도 안보이는 현상이 나타나기도 한다. 버그인가 본데, 이런 현상이 나타나면, 화면 크기를 줄이거나 늘리면 정상적으로 표시된다. 이제 나머지 과정은 다른 Plugin과 동일하다.

STS가 Restart 되었다면, Gradle이 정상적으로 설치되었는 지 확인해 보도록 하자. 아래 메뉴를 click 해 보자

File > New > Other...

그래서 아래와 같이 화면에 Gradle이 표시되면 정상적으로 설치된 것이다.

gradle-확인

Spring Framework 4.0 무엇이 달라졌나?

아래 내용은 spring.io에 설명된 내용을 번역한 것입니다. 기술적인 내용 중에는 저도 잘 모르는 부분이 있어, 명확하지는 않습니다. 그저, 어떤 것들이 3.0과 달라졌는 지를 훑어 보는 데에는 도움이 될 것입니다.

New Features and Enhancements in Sping Framework 4.0

Spring Framework은 2004년에 처음 release되었다. Spring 2.0은 XML namespace와 AspectJ support를 제공했고, Spring 2.5는 annotation 기반의 설정 방법을 포함하였다. Spring 3.0에서는 Java 5를 지원했고, Java-based @Configuration model을 지원했다.

Version 4.0은 Java 8의 모든 기능을 지원하는 첫 번째 Spring version이다. 그렇지만, 여전히 이전 버전의 Java version을 지원한다(최소 요구사항은 Java 6)

1. Improved Getting Started Experience

spring.io 웹사이트는 Spring을 익히기 위한 “Getting Started” guide의 전체 시리즈를 제공한다. 이 document에 있는 “Chapter 1, Getting Started With Spring” section에서 더 많은 것을 읽을 수 있다. 또한 이 사이트에서는 Spring umbrella 아래에서 배포된 많은 추가 프로젝트를 제공한다.

2. Removed Deprecated Packages and Methods

Deprecated된 모든 package와 method들이 이번 4.0 버전에서 삭제되었다.

추가/삭제/변경된 모든 package 정보들을 확인하고 싶다면, API Difference Report를 보면 된다.

Optional third-party dependency에 대해서는 2010년 말 이후에 release된 버전을 지원한다. 예외적으로 Hibernate Validator는 4.3 이상을, Jackson은 2.0 이상을 지원한다.

3. Java 8 (as well as 6 and 7)

Spring Framework 4.0은 Java 8을 지원한다. lambda expression을 사용할 수 있으며, Spring callback interface에 method 참조를 사용할 수 있다. 몇 가지 annotation은 “@Repeatable” 처럼 개조되었다. 

Spring 4는 JDK 6 update 18부터 지원을 하지만, 새로 시작하는 프로젝트는 JDK 7 또는 8로 개발할 것을 권장한다.

4. Java EE 6 and 7

Java EE 6 이상에서 JPA 2.0과 Servlet 3.0이 고려되어졌다. Goole App Engine과 더 오래된 application server들을 위해 Serlvet 2.5에 배포하는 것도 가능하다. 그러나, 테스트 환경을 위해서는 Servlet 3.0 이상을 사용할 것을 권장한다.

5. Groovy Bean Definition DSL

Groovy DSL을 사용하여 외부 bean 설정을 하는 것이 가능해 졌다. XML bean definition을 사용하는 것과 유사하다. 그러나, 좀 더 간결한 문장을 사용할 수 있다. Groovy를 사용하면, 개발 초기 단계에서 설정을 쉽게 embed하여 사용할 수 있도록 해 준다. 예를 들어,

def reader = new GroovyBeanDefinitionReader(myApplicationContext)
reader.beans {
    dataSource(BasicDataSource) {
        driverClassName = "org.hsqldb.jdbcDriver"
        url = "jdbc:hsqldb:mem:grailsDB"
        username = "sa"
        password = ""
        settings = [mynew:"setting"]
    }
    sessionFactory(SessionFactory) {
        dataSource = dataSource
    }
    myService(MyService) {
        nestedBean = { AnotherBean bean ->
            dataSource = dataSource
        }
    }
}

위와 같이, Datasource를 코드에서 쉡게 정의하여 사용할 수 있다.

6. Core Container Improvements

다음은 Core container의 몇 가지 향상된 점들이다.

  • Spring은 Bean을 injecting할 때, generic type을 다룰 수 있다. 예를 들어, Spring Data “Repository”를 사용할 때, 정의된 구현제를 쉽게 사용할 수 있다. more…
  • Spring의 meta-annotation을 사용한다면, Source annotation에서 attribute를 재정의하는 것이 가능하다.
  • Bean들은 list나 array에 autowired 될 때, 정렬이 될 수 있다. @Order 혹은 Ordered interface를 사용해서…
  • @Lazy annotation도 injection 시점에서 사용될 수 있다.
  • Java-based configuration을 사용하는 개발자들을 위해 @Description annotation이 추가되었다.
@Configuration
public class AppConfig {

    @Bean
    @Desciption("Provides a basic example of a bean")
    public Foo foo() {
        return new Foo();
    }

}
  • Conditionally filtering bean을 위한 generalized model은 “@Conditional” annotation을 통해 추가된다. 이것은 “@Profile”과 유사하지만, user-defined strategy가 programmatically하게 개발되는 것을 가능하게 한다.(무슨 말이야…)
  • CGLIB-based proxy classes는 더 이상 default constructor를 필요로 하지 않는다.
  • Time zone이 framework 전반에 걸쳐 관리되어 진다. (LocaleContext)

7. General Web Improvements

Servlet 2.5 server에 배포하는 것은 선택사항이다. 그러나, Spring 4.0은 Servlet 3.0이상의 환경에 배포하는 것에 초점이 맞추어져 있다. 만일, Spring MVC Test Framework을 사용한다면, 반드시 Servlet 3.0 환경이어야 한다.뒤에 언급될 WebSocket 지원 외에도, 다음 개선 사항들이 포함되어 있다.

  • @RestController annotation을 사용할 수 있다. @RequestMapping method에 @ResponseBody를 붙이지 않아도 된다.
  • AsyncRestTemplate class가 추가되었다. 이것은 REST client를 개발할 때, Non-blocking asynchronous를 지원한다. more…
  • Spring MVC application을 개발할 때, comprehensive timezone을 지원한다. more…

8. WebSocket, SockJS, and STOMP Messagin

spring-websocket은 웹애플리케이션에서 client와 server간의 WebSocket-based two-way communication을 지원한다. fully. (여기서 말하는 Two-way는 일반적인 TCP 통신을 의미함.) 또한 아직 WebSocket protocol을 지원하지 않는 브라우저를 위해 SockJS-based fallback option도 제공한다. 새로운 spring-messaging module은 STOMP에 대한 지원도 추가한다.

9. Testing Improvements

Spring 4.0은 몇 가지 새로운 기능을 추가했다.

  • spring-test에 있는 대부분의 annotation은 meta-annotation으로 사용될 수 있다.
  • Active bean definition profile은 programmatically하게 만들 수 있다. @ActiveProfiles의 resolver attribute을 통해.
  • spring-core에 SocketUtils가 추가되었다. 이것은 localhost에서 TCP와 UDP 서버 port를 scan할 수 있도록 해 준다.
  • org.springframework.mock.web에 있는 mock set들은 이제 Servlet 3.0 API를 기반으로 동작한다.

– 끝 –

Maven Tomcat plugin 설정

Apache Tomcat을 maven으로 실행하기 위한 pom.xml 설정

<build>
    <plugins>
    :
        <!-- tomcat -->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <charset>UTF-8</charset>
                <uriEncoding>UTF-8</uriEncoding>
                <path>${tomcat.path}</path>
                <port>${tomcat.port}</port>
                <url>${tomcat.url}</url>
                <username>${tomcat.username}</username>
                <password>${tomcat.password}</password>
            </configuration>
        </plugin>
    </plugins>
    :
</build>

Tomcat을 실행하기 위한 maven 명령

mvn clean install tomcat7:run