simple-command
项目是simple-webapp
的一个命令行版本。这个命令行工具有这同样的模块依赖:simple-persist
和simple-weather
。现在你需要从命令行运行这个simple-command
工具,而非通过web浏览器与该应用交互。
Example 7.19. simple-command 的 POM
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.sonatype.mavenbook.ch07</groupId> <artifactId>simple-parent</artifactId> <version>1.0</version> </parent> <artifactId>simple-command</artifactId> <packaging>jar</packaging> <name>Simple Command Line Tool</name> <build> <finalName>content-zh</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <testFailureIgnore>true</testFailureIgnore> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>hibernate3-maven-plugin</artifactId> <version>2.1</version> <configuration> <components> <component> <name>hbm2ddl</name> <implementation>annotationconfiguration</implementation> </component> </components> </configuration> <dependencies> <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>1.8.0.7</version> </dependency> </dependencies> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.sonatype.mavenbook.ch07</groupId> <artifactId>simple-weather</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.sonatype.mavenbook.ch07</groupId> <artifactId>simple-persist</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>2.0.7</version> </dependency> <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>1.8.0.7</version> </dependency> </dependencies> </project>
这个POM创建一个包含了如Example 7.20, “simple-command 的 Main 类”所示的org.sonatype.mavenbook.weather.Main
类的JAR文件。在这个POM中我们配置了Maven
Assembly插件使用内置的名为jar-with-dependencies
的装配描述符来创建一个JAR文件,该文件包含了运行应用所需要的所有二进制代码,包括项目本身的字节码以及所有依赖文件的字节码。
Example 7.20. simple-command 的 Main 类
package org.sonatype.mavenbook.weather; import java.util.List; import org.apache.log4j.PropertyConfigurator; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.sonatype.mavenbook.weather.model.Location; import org.sonatype.mavenbook.weather.model.Weather; import org.sonatype.mavenbook.weather.persist.LocationDAO; import org.sonatype.mavenbook.weather.persist.WeatherDAO; public class Main { private WeatherService weatherService; private WeatherDAO weatherDAO; private LocationDAO locationDAO; public static void main(String[] args) throws Exception { // Configure Log4J PropertyConfigurator.configure(Main.class.getClassLoader().getResource( "log4j.properties")); // Read the Zip Code from the Command-line (if none supplied, use 60202) String zipcode = "60202"; try { zipcode = args[0]; } catch (Exception e) { } // Read the Operation from the Command-line (if none supplied use weather) String operation = "weather"; try { operation = args[1]; } catch (Exception e) { } // Start the program Main main = new Main(zipcode); ApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "classpath:applicationContext-weather.xml", "classpath:applicationContext-persist.xml" }); main.weatherService = (WeatherService) context.getBean("weatherService"); main.locationDAO = (LocationDAO) context.getBean("locationDAO"); main.weatherDAO = (WeatherDAO) context.getBean("weatherDAO"); if( operation.equals("weather")) { main.getWeather(); } else { main.getHistory(); } } private String zip; public Main(String zip) { this.zip = zip; } public void getWeather() throws Exception { Weather weather = weatherService.retrieveForecast(zip); weatherDAO.save( weather ); System.out.print(new WeatherFormatter().formatWeather(weather)); } public void getHistory() throws Exception { Location location = locationDAO.findByZip(zip); List<Weather> weathers = weatherDAO.recentForLocation(location); System.out.print(new WeatherFormatter().formatHistory(location, weathers)); } }
这个Main
类有对于WeatherDAO
,
LocationDAO
, 以及
WeatherService
的引用。该类的静态main()
方法:
-
从第一个命令行参数读取邮编。
-
从第二个命令行参数读取操作。如果操作是“weather”,最新的天气将会从web服务获得。如果操作是“history”,该程序会从本地数据库获取历史天气记录。
-
根据来自于
simple-persist
和simple-weather
的两个XML文件载入SpringApplicationContext
。 -
创建一个
Main
的实例。 -
使用来自于Spring
ApplicationContext
的bean填充weatherService
,weatherDAO
, 和locationDAO
。 -
根据特定的操作运行相应的
getWeather()
或者getHistory()
方法。
在web应用中我们使用Spring
VelocityViewResolver
来呈现一个Velocity模板。在这个单机实现中给我们需要编写一个简单的类来通过Velocity模板呈现天气数据。Example 7.21, “WeatherFormatter 使用 Velocity 模板呈现天气数据”是WeatherFormatter
的代码清单,这个类有两个方法来呈现天气报告和天气历史信息。
Example 7.21. WeatherFormatter 使用 Velocity 模板呈现天气数据
package org.sonatype.mavenbook.weather; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringWriter; import java.util.List; import org.apache.log4j.Logger; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.sonatype.mavenbook.weather.model.Location; import org.sonatype.mavenbook.weather.model.Weather; public class WeatherFormatter { private static Logger log = Logger.getLogger(WeatherFormatter.class); public String formatWeather( Weather weather ) throws Exception { log.info( "Formatting Weather Data" ); Reader reader = new InputStreamReader( getClass().getClassLoader(). getResourceAsStream("weather.vm")); VelocityContext context = new VelocityContext(); context.put("weather", weather ); StringWriter writer = new StringWriter(); Velocity.evaluate(context, writer, "", reader); return writer.toString(); } public String formatHistory( Location location, List<Weather> weathers ) throws Exception { log.info( "Formatting History Data" ); Reader reader = new InputStreamReader( getClass().getClassLoader(). getResourceAsStream("history.vm")); VelocityContext context = new VelocityContext(); context.put("location", location ); context.put("weathers", weathers ); StringWriter writer = new StringWriter(); Velocity.evaluate(context, writer, "", reader); return writer.toString(); } }
weather.vm
模板简单的打印邮编对应的城市,国家,区域以及当前的气温。history.vm
模板打印位置信息并遍历存储在本地数据库中的天气预报记录。两者都位于/data/hudson-temporal-data/hudson-orchestrator-home/workspace/Book-To-Production/content-zh/src/main/resources
。
Example 7.22. weather.vm Velocity 模板
**************************************** Current Weather Conditions for: ${weather.location.city}, ${weather.location.region}, ${weather.location.country} **************************************** * Temperature: ${weather.condition.temp} * Condition: ${weather.condition.text} * Humidity: ${weather.atmosphere.humidity} * Wind Chill: ${weather.wind.chill} * Date: ${weather.date}
Example 7.23. history.vm Velocity 模板
Weather History for: ${location.city}, ${location.region}, ${location.country} #foreach( $weather in $weathers ) **************************************** * Temperature: $weather.condition.temp * Condition: $weather.condition.text * Humidity: $weather.atmosphere.humidity * Wind Chill: $weather.wind.chill * Date: $weather.date #end