源码下载链接:
**本篇博客主要是在上述两个工程的基础上,仿照stsm工程为gtvg集成spring框架,使其@Controller等元数据,通过对
Thymeleaf +Spring官方文档的解读,参照Spring Expression Language (SpEL)语言规则对gtvg进行适当的修改。**
本次实验主要是在gtvg的基础上进行修改,其项目的基本结构保持不变。
第一步:Maven工程首先应该配置pom.xml,添加需要的依赖
主要的修改为: artifactId 修改为 my_mvn, 添加Spring框架版本及相应的Spring依赖。
pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- ========================================================================= -->
<!-- -->
<!-- Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) -->
<!-- -->
<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
<!-- you may not use this file except in compliance with the License. -->
<!-- You may obtain a copy of the License at -->
<!-- -->
<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
<!-- -->
<!-- Unless required by applicable law or agreed to in writing, software -->
<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
<!-- implied. See the License for the specific language governing -->
<!-- permissions and limitations under the License. -->
<!-- -->
<!-- ========================================================================= -->
<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>
<groupId>thymeleafexamples</groupId>
<artifactId>my_mvn</artifactId>
<packaging>war</packaging>
<version>ci</version>
<name>Thymeleaf Examples - My Sring Thymeleaf MVC </name>
<description>XML/XHTML/HTML5 template engine for Java</description>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<organization>
<name>The THYMELEAF team</name>
<url>http://www.thymeleaf.org</url>
</organization>
<scm>
<url>scm:git:git@github.com:thymeleaf/thymeleafexamples-stsm.git</url>
<connection>scm:git:git@github.com:thymeleaf/thymeleafexamples-stsm.git</connection>
<developerConnection>scm:git:git@github.com:thymeleaf/thymeleafexamples-stsmgit</developerConnection>
</scm>
<developers>
<developer>
<id>dfernandez</id>
<name>Daniel Fernandez</name>
<email>daniel.fernandez AT 11thlabs DOT org</email>
<roles>
<role>Project admin</role>
</roles>
</developer>
</developers>
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<springframework.version>4.3.3.RELEASE</springframework.version>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.html</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>ISO-8859-1</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>build-dist</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-assembly-dist</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${basedir}/src/assembly/sources.xml</descriptor>
</descriptors>
<appendAssemblyId>true</appendAssemblyId>
<finalName>${project.groupId}-${project.artifactId}-${project.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${thymeleaf.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>4.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
SpringServletInitializer.Java不必修改,只需修改SpringWebConfig.java(对于该文件,我们也可以以beans.xml的形式实现),删除原有的addFormatters、varietyFormatter、dateFormatter等方法,因为我们在gtvg中并不需要stsm的VarietyFormatter等类,同时修改viewResolver方法,添加 viewResolver.setCharacterEncoding(“UTF-8”),使其编码方式为 “UTF-8”,否则中文会乱码。由于我们已经有了SpringWebConfig.java 来实现配置,那么就可以删掉web.xml文件,filter包也用不到,删掉。
package thymeleafexamples.gtvg.application;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
/*import thymeleafexamples.stsm.web.conversion.DateFormatter;
import thymeleafexamples.stsm.web.conversion.VarietyFormatter;*/
@Configuration
@EnableWebMvc
@ComponentScan("thymeleafexamples.gtvg")
public class SpringWebConfig
extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private ApplicationContext applicationContext;
public SpringWebConfig() {
super();
}
public void setApplicationContext(final ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
/* ******************************************************************* */
/* GENERAL CONFIGURATION ARTIFACTS */
/* Static Resources, i18n Messages, Formatters (Conversion Service) */
/* ******************************************************************* */
/**
* Dispatcher configuration for serving static resources
*/
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
/**
* Message externalization/internationalization
*/
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("Messages");
return messageSource;
}
/* **************************************************************** */
/* THYMELEAF-SPECIFIC ARTIFACTS */
/* TemplateResolver <- TemplateEngine <- ViewResolver */
/* **************************************************************** */
@Bean
public SpringResourceTemplateResolver templateResolver(){
// SpringResourceTemplateResolver automatically integrates with Spring's own
// resource resolution infrastructure, which is highly recommended.
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
// HTML is the default value, added here for the sake of clarity.
templateResolver.setTemplateMode(TemplateMode.HTML);
// Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(true);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(){
// SpringTemplateEngine automatically applies SpringStandardDialect and
// enables Spring's own MessageSource message resolution mechanisms.
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
// Enabling the SpringEL compiler with Spring 4.2.4 or newer can
// speed up execution in most scenarios, but might be incompatible
// with specific cases when expressions in one template are reused
// across different data types, so this flag is "false" by default
// for safer backwards compatibility.
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
//
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
第三步: 修改控制器
因为我们使用@Controller、@RequestMapping等元数据,可以删除gtvg原有controller包下的所有控制器,进行重写,我下面实现了3个控制器,如图所示:
对于GTVGController.java,主要实现基本的地址请求,实现如下:
package thymeleafexamples.gtvg.web.controller;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import thymeleafexamples.gtvg.business.entities.User;
import thymeleafexamples.gtvg.business.entities.Order;
import thymeleafexamples.gtvg.business.entities.Product;
import thymeleafexamples.gtvg.business.services.OrderService;
import thymeleafexamples.gtvg.business.services.ProductService;
@Controller
public class GTVGController {
@Autowired
private ProductService productService;
@Autowired
private OrderService orderService;
public GTVGController() {
// TODO Auto-generated constructor stub
super();
}
@ModelAttribute("today")
public Date getToday() {
return Calendar.getInstance().getTime();
}
@ModelAttribute("prods")
public List<Product> showALlProducts() {
return this.productService.findAll();
}
@ModelAttribute("orders")
public List<Order> showAllOrders() {
return this.orderService.findAll();
}
@RequestMapping({"/", "/gtvg"})
public String showHome(HttpSession session) {
session.setAttribute("user", new User("John", "Apricot", "Antarctica", null));
return "home";
}
@RequestMapping("/userprofile")
public String showUserProfile() {
return "userprofile";
}
@RequestMapping("/subscribe")
public String showSubscribe() {
return "subscribe";
}
@RequestMapping("/product/list")
public String showProductList() {
return "/product/list";
}
@RequestMapping("/order/list")
public String showOrderList() {
return "/order/list";
}
}
大部分工作已经完成,最后就需要修改资源文件(.properties,.html)
properties 文件
在SpringWebConfig.java 有一个messageSource方法,就是用于管理资源文件的(含有@Bean注解的类,均可以在beans.xml文件中配置)。
.properties文件是用于实现文字国际化表达的:
参考stms的目录,可以发现,它的_.properties文件都是集中在Messages.properties中messageSource.setBasename(“Messages”);
因此,在src/main/resources 下新建Messages.properties 文件,将gtvg原有templates文件夹下的properties文件复制到对应版本的。.html 文件
由于使用Spring集成,在Thymeleaf 中使用的方言有些符合OGNL,但是却不符合SpEL(Spring Expression Language), 因此我们应作出相应的修改。
比如:
对于order/list.html, 应该将{#aggregates.sum(o.orderLines.{purchasePrice * amount})}修改为{#aggregates.sum(o.orderLines.![purchasePrice * amount])}
对于order/details.html 也要作上述修改,还有 SpEL 在 ‘{th:object,data-th-object}’ 只支持(${…}),
因此需要将修改为
第五步:到此为止,我们完成了Spring的集成工作,可以检验一下我们的结果,clean compile tomcat7:run 运行程序,与原有gtvg的项目结果进行比对,如果完全一样,则我们正确集成了Spring。
注意:测试时根URI为localhost:8080/my_mvn/, my_mvn是我们的工程名