Velocity 템플릿 엔진 시작

Velocity Template Engine을 사용하면 애플리케이션 및 서블릿 내에서 데이터를 렌더링 할 수 있습니다. 주로 동적 서블릿 기반 웹 사이트를 개발하는 데 사용되는 Velocity의 템플릿과 Java 코드를 깔끔하게 분리하여 MVC 웹 개발에 이상적입니다. 일반적인 템플릿 엔진 인 Velocity는 코드 생성, XML 생성 및 변환, 텍스트 스트림 처리와 같은 다른 많은 목적에 적합합니다. 이 기사에서는 VTL (Velocity Template Language)을 소개하고 Java 서블릿 환경에서 웹 컨텐츠를 생성하는 방법을 포함하여 Velocity 엔진을 사용하는 방법에 대한 예제를 제공합니다.

Velocity는 국제 자원 봉사자 커뮤니티에서 개발하고 Apache Software Foundation의 Jakarta Project에서 호스팅하는 오픈 소스 템플릿 도구입니다. 무료로 제공되는 소스 코드를 다운로드 할 수있는 Jakarta Velocity 프로젝트 웹 사이트에서 번성하고 성장하는 사용자 커뮤니티는 질문에 답하고 일반적인 템플릿 문제에 대한 솔루션을 제공 할 준비가되어 있습니다. Velocity는 선구적인 WebMacro 프로젝트에서 영감을 얻었으며 Velocity 커뮤니티의 우리가 감사하는 작업입니다.

이 기사에서는 Velocity Template Engine과 템플릿 언어 인 VTL (Velocity Template Language)에 대한 짧은 입문서를 제시합니다. 또한 몇 가지 예제를 통해 Velocity를 사용하는 방법을 보여줍니다.

물론 Hello World

Hello World 예제 없이는 프로그래밍 관련 주제에 대한 설명이 완료되지 않습니다. Velocity를 사용하는 모든 응용 프로그램에는 두 부분이 필요합니다. 첫 번째는 템플릿으로,이 예제에서는 다음과 같은 파일입니다 helloworld.vm.

안녕하세요 $ name! Velocity에 오신 것을 환영합니다!

두 번째는 다음과 같은 해당 Java 프로그램입니다 HelloWorld.java.

import java.io.StringWriter; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; public class HelloWorld {public static void main (String [] args) throws Exception {/ * 먼저 엔진을 가져오고 초기화합니다. * / VelocityEngine ve = new VelocityEngine (); ve.init (); / * 다음으로 템플릿을 가져옵니다. * / Template t = ve.getTemplate ( "helloworld.vm"); / * 컨텍스트 생성 및 데이터 추가 * / VelocityContext context = new VelocityContext (); context.put ( "이름", "세계"); / * 이제 템플릿을 StringWriter로 렌더링 * / StringWriter writer = new StringWriter (); t.merge (context, writer); / * 세계를 보여줍니다 * / System.out.println (writer.toString ()); }}

이제이 프로그램을 컴파일하고 실행하면 출력이 표시됩니다.

안녕하세요! Velocity에 오신 것을 환영합니다!

이것은 사소한 예이지만 Velocity 템플릿이 무엇인지에 대한 아이디어를 제공하는 중요한 부분이 포함되어 있습니다.

왜 사용해야합니까?

사용하기 쉬운 일반 템플릿 도구로 설계된 Velocity는 데이터 형식화 및 표시가 필요한 모든 Java 애플리케이션 영역에서 유용합니다. 다음과 같은 이유로 Velocity를 사용해야합니다.

  • 그것은 많은 응용 분야에 적응합니다
  • 템플릿 디자이너를위한 간단하고 명확한 구문을 제공합니다.
  • 개발자를위한 간단한 프로그래밍 모델을 제공합니다.
  • 템플릿과 코드가 분리되어 있기 때문에 독립적으로 개발하고 유지할 수 있습니다.
  • Velocity 엔진은 모든 Java 애플리케이션 환경, 특히 서블릿에 쉽게 통합됩니다.
  • Velocity를 사용하면 템플릿이 컨텍스트에서 데이터 개체의 모든 공개 방법에 액세스 할 수 있습니다.

마지막 요점은 중요합니다. 즉, 기존 클래스를 재사용 할 수 있습니다. 따라서 템플릿에서 사용하려는 객체는 JavaBeans와 같은 특정 방식으로 구조화되거나 JSP (JavaServer Pages) taglibs와 같은 특수 I / O 또는 라이프 사이클 모드를 구현할 필요가 없습니다. 유일한 요구 사항은 메서드가 공용이라는 것입니다. 템플릿 언어를 자세히 다룰 때 더 많은 것을 보게 될 것입니다.

Velocity의 강점 중 하나는 애플리케이션 내에서 기능적 책임의 분리를 강력하게 시행한다는 것입니다. 이는 애플리케이션 코드가 특별히 제공하는 객체에 대한 템플릿 액세스를 제한하여 수행합니다. 즉, 디자이너는 데이터 표현 (뷰)에만 집중할 수 있으며, 애플리케이션 프로그래머는 MVC (Model-View-Controller)에서 애플리케이션 제어 (컨트롤러)와 비즈니스 로직 및 데이터 관리 (모델)에 집중할 수 있습니다. 개발. MVC는 정교한 응용 프로그램의 개발과 지속적인 유지 관리를 모두 단순화하는 잘 수용된 개발 패턴입니다.

어디서 사용하나요?

Velocity는 다음에서 성공적으로 사용됩니다.

  • 서블릿 기반 웹 애플리케이션
  • Java 및 SQL 코드 생성
  • XML 처리 및 변환
  • RTF 파일 생성과 같은 텍스트 처리

Velocity는 JSP 및 기타 렌더링 기술 대신 또는 이와 함께 Java 서블릿 기반 웹 애플리케이션 개발을위한 렌더링 엔진으로 가장 일반적으로 사용됩니다. 쉽고 유지 보수가 가능한 템플릿 구문 외에도 Velocity는 템플릿 언어가 데이터를 생성하는 것이 아니라 데이터를 조작하고 표현할 수 있기 때문에 웹 개발에 사용됩니다. 이것은 템플릿 내의 프로그래밍을 권장하지 않습니다 . 이것은 좋은 것입니다. Java 코드의 비즈니스 및 애플리케이션 로직이 속한 곳에 유지됩니다.

Velocity는 플랫폼이 JSP 이외의 출력 기술을 수용하기 때문에 J2EE (Java 2 Platform, Enterprise Edition) 웹 개발에 적합합니다. JSP는 J2EE 사양에 포함되어 있지만 J2EE는 사용할 필요가 없습니다.

어떻게 작동합니까?

You use the same general process to create a Velocity-based application as you would any application. Let's consider a more interesting example than the Hello World application above. Suppose you operate a pet store and wish to generate an email blast to announce a sale. First, you must design the email and then develop the template and code based on that design.

Design-time considerations

You need to consider three elements for your design:

  • Which data to include in the email
  • What form the data elements should take (for example, as List, Map, or String)
  • What to call those data elements

For this example, let's suppose you decide on three pets for sale, each with a different advertised price. You decide to use a map to associate each pet name and its price, and then store all three maps in a list. You call this list petList, the pet name name, and the price as price in the map. Now that you have identified the relevant data, its representation, and naming criteria, you can write the code and the template's design.

Write the code and template design

Once you agree on data specifics, Velocity lets you write the code and design the template in parallel. The designer integrates the data into the nondata presentation content (like images, text, and so on) in the template. In this case, we simply write in the email body:

 $petList.size() Pets on Sale! We are proud to offer these fine pets at these amazing prices. This month only, choose from: #foreach( $pet in $petList ) $pet.name for only $pet.price #end Call Today! 

As the programmer, you must:

  • Retrieve all data from the data sources -- a database via JDBC (Java Database Connectivity), a file, or just something calculated
  • Put that data into the context using the agreed-upon names
  • Render the template with the context to produce output

You may recall from the Hello World example that I referred to class VelocityContext as the context. Modeled after a java.util.Map, the context is an object that holds data provided by the application or servlet that the template accesses.

For this example, we get all the data from our data sources (in this case, we hardwire it into the code), organize it, and add it to the context:

 /* create our list of maps */ ArrayList list = new ArrayList(); Map map = new HashMap(); map.put("name", "horse"); map.put("price", "00.00"); list.add( map ); map = new HashMap(); map.put("name", "dog"); map.put("price", "9.99"); list.add( map ); map = new HashMap(); map.put("name", "bear"); map.put("price", ".99"); list.add( map ); /* add that list to a VelocityContext */ VelocityContext context = new VelocityContext(); context.put("petList", list); 

It appears we really want to get rid of those bears!

Now, with the data organized and placed in the context and the template ready, we can render the template against the context. Here is the code:

import java.io.StringWriter; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; public class PetStoreEmail { public static void main( String[] args ) throws Exception { /* first, get and initialize an engine */ VelocityEngine ve = new VelocityEngine(); ve.init(); /* organize our data */ ArrayList list = new ArrayList(); Map map = new HashMap(); map.put("name", "horse"); map.put("price", "00.00"); list.add( map ); map = new HashMap(); map.put("name", "dog"); map.put("price", "9.99"); list.add( map ); map = new HashMap(); map.put("name", "bear"); map.put("price", ".99"); list.add( map ); /* add that list to a VelocityContext */ VelocityContext context = new VelocityContext(); context.put("petList", list); /* get the Template */ Template t = ve.getTemplate( "petstoreemail.vm" ); /* now render the template into a Writer */ StringWriter writer = new StringWriter(); t.merge( context, writer ); /* use the output in your email body */ sendEmail( writer.toString() ); } } 

This complete program generates your email body. Because Velocity renders templates into a Writer, you can easily manage the output. In this case, the rendered output went into a String via the StringWriter, but it could easily have gone to a file, a browser, or a BLOB (binary large object) in a database. This is one reason why Velocity integrates so easily into Java applications.

The program output (your email body) looks like this:

 3 Pets on Sale! We are proud to offer these fine pets at these amazing prices. This month only, choose from: horse for only 00.00 dog for only 9.99 bear for only .99 Call Today! 

Velocity Template Language

I've shown Velocity templates for two different examples, but in neither case have I explained what the special markup did (although you could probably guess).

The Velocity Template Language (VTL) is a simple syntax providing two parts: references, a formalism for accessing objects in the context; and directives, a set of statements used for control and action. Described as "a language definition with a feature set that fits comfortably on a standard business card" (see Jim Jagielski's "Getting Up to Speed with Velocity") VTL has been intentionally kept simple and small by the community.

References

References in the template access data. They freely mix with the template's non-VTL content. Formally defined, a reference is anything in a template that starts with the '$' character and refers to something in the context. If no corresponding data object exists in the context, the template simply treats the reference as text and renders it as-is into the output stream.

Here is a short template containing a simple reference mixed with non-VTL content:

 Hello $name! Welcome to Velocity! 

Here, the reference is $name. As in the Hello World example, Velocity replaces $name in the template with the toString() return value of what is placed in the context under the key name:

 Hello World! Welcome to Velocity! 

The Velocity reference allows access to any object's public method, and the template's syntax is the same as it would be in Java code. Here are a few examples:

 There are $myBean.getSize() elements. $myObject.anotherMethod( 1, "more data ") $foo.getBar().barMethod("hello", $moredata ) $foo.myMethod( $bar.callThis() ) 

You may recall from the Pet Store email example that we stored the name and price information in a java.util.Map, and accessed the data using two tokens name and price, which don't exist as methods in the java.util.Map class:

 $pet.name for only $pet.price 

This works because Velocity incorporates a JavaBean-like introspection mechanism that lets you express method accesses in references using a property notation. In the Pet Store example template, Velocity's introspection facility finds and invokes the Map's public Object get(String) method with the keys name and price. We could access the same data in a different way by invoking the get(String) method directly in the template:

 $pet.get('name') for only $pet.get('price') 

이것은 동일한 출력을 생성하고 실제로 일어나는 일을 더 잘 나타냅니다. 그러나 속성 표기법을 사용하는 다른 방법은 읽기가 더 쉽고 템플릿을 데이터 클래스의 특정 구현에 연결하지 않습니다. 예를 들어, 당신은 대체 할 수 Map의를 List공용 메소드가있는 클래스 getName()getPrice(), 작업을 계속 다음을 포함하는 원래 예제 템플릿 :

 $ pet.name에 $ pet.price 만