分享

SpringMVC和Freemarker整合,带自定义标签的使用方法。

 真爱图书 2014-12-25

最近一直在用SpringMVC这个框架,它基于注解的特点非常好用。Freemarker具有很多出色的内置方法,与js可以完美搭配使用,用作SpringMVC的view层感觉良好。这里写一篇文章简要说明如何整合SpringMVC与Freemarker,以及如何去使用它的自定义标签。


一、jar包准备

首先是Spring、SpringMVC的依赖jar包……

然后是Freemarker的依赖jar包,我使用的是freemarker-2.3.20.jar,如果使用maven的话可以直接在pom.xml中添加一段把它引进来:

  1. <groupId>org.freemarker</groupId>  
  2. <artifactId>freemarker</artifactId>  
  3.  <version>2.3.20</version>  


二、配置web.xml

  1. <?xml version="1.0" ?>  
  2. <web-app xmlns="http://java./xml/ns/javaee" xmlns:xsi="http://www./2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_3_0.xsd"  
  4.     version="3.0">  
  5.     <!--  Spring 服务层的配置文件 -->  
  6.     <context-param>  
  7.         <param-name>contextConfigLocation</param-name>  
  8.         <param-value>classpath:applicationContext.xml</param-value>  
  9.     </context-param>  
  10.       
  11.     <!--  Spring 容器启动监听器 -->  
  12.     <listener>  
  13.         <listener-class>org.springframework.web.context.ContextLoaderListener  
  14.         </listener-class>  
  15.     </listener>  
  16.   
  17.     <servlet>  
  18.         <servlet-name>springmvc</servlet-name>  
  19.         <servlet-class>org.springframework.web.servlet.DispatcherServlet  
  20.         </servlet-class>  
  21.         <load-on-startup>1</load-on-startup>  
  22.     </servlet>  
  23.     <!--为DispatcherServlet建立映射 -->  
  24.     <servlet-mapping>  
  25.         <servlet-name>spring</servlet-name>  
  26.         <url-pattern>/</url-pattern>  
  27.     </servlet-mapping>  
  28. </web-app>  

三、配置spring-servlet.xml

这里只写上freemarker的配置部分,先配置视图解析器:

  1. <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
  2.     <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>  
  3.     <property name="contentType" value="text/html; charset=utf-8"/>  
  4.     <property name="suffix" value=".ftl" />   <!-- 本行配置文件类型,freemarker文件类型标准是ftl -->  
  5.     <!-- 如果有多种解析器,添加下面这行,让freemarker解析器优先 -->  
  6.     <property name="order" value="0" />  
  7. </bean>  

接下来加上freemarker的配置

  1. <bean id="freemarkerConfig"  
  2.     class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
  3.     <property name="templateLoaderPath">  
  4.         <value>/WEB-INF/t/</value>  <!-- 你的模版文件的存放路径,我这里存放在WEB-INF目录下的t文件夹里 -->  
  5.     </property>  
  6.     <property name="defaultEncoding">  
  7.         <value>utf-8</value>  
  8.     </property>  
  9.     <property name="freemarkerSettings">  
  10.         <props>  
  11.             <prop key="template_update_delay">3600</prop>  <!-- 模版更新间隔,开发时设为1,项目工作时建议设置为较大数字-->  
  12.         </props>   
  13.     </property>  
  14.     <!-- 假设你需要使用freemarker的自定义标签,这里还需要增加这一段 -->  
  15.     <property name="freemarkerVariables">  
  16.         <map>  
  17.         <entry key="XXDirective" value-ref="XXDirective"/>      
  18.         <!-- 这里配置的是自定义标签,建议命名为XXDirective,有多个就一起在这里配置 -->  
  19.         </map>     
  20.     </property>  
  21. </bean>  
  22. <!-- 使用自定义标签还需要配置自定义标签的bean,不使用自定义标签不用写 -->  
  23. <bean id="XXDirective" class="..XXDirective"/>   



四、编写Controller

  1. @RequestMapping(value = "/document/getArticle.action")  
  2. public String getColumn( ModelMap root) throws Exception {  
  3.     root.put(“art_content”, “这是一篇文章”);  
  4.     return article;//与模版名称相对应   
  5. }  

五、在前面配置的模版路径下编写article.ftl

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. </head>  
  5. <body>  
  6.     ${art_content}              
  7. </body>  
  8. </html>  

那么访问getArticle.action则跳转到页面输出结果:这是一篇文章


六、自定义标签的使用

这里例举一个最简单的用法,我的数据库中有一个文章表(文章有很多属性title、content等),假设我需要在article.ftl的页面上指定我需要取id=5的这篇文章标题和内容,这时候,就可以用到自定义标签了。(用法很多,这里只简单介绍一下)

 

首先编写一个自定义标签类实现TemplateDirectiveModel接口:

  1. public class ArticleDirective implements TemplateDirectiveModel {  
  2.     public void execute(Environment env, Map params, TemplateModel[] loopVars,TemplateDirectiveBody body) throws TemplateException {      
  3.     Object paramValue = params.get("articleId"); //这里模版页面传进来的参数叫做articleId   
  4.     int id=0;  
  5.         if (paramValue instanceof TemplateNumberModel) {  
  6.         id = ((TemplateNumberModel) paramValue).getAsNumber().intValue();  
  7.     }                                                                                                                                 
  8. <span style="white-space:pre">    </span>/* Freemarker自定义标签不能直接识别传过来的数据类型参数,例如参数是字符串类型的参数,则用到SimpleScalar,比方说参数param是一个String,那么要先将参<span style="white-space:pre">    </span>数强转为SimpleScalar类型再使用其getAsString方法。                                
  9.     String id= (SimpleScalar) params.get("param").getAsString();  
  10.     参数还可以是集合、数组类型、这里不一一介绍 */  
  11.     Article article = ArticleService.getArticleById(id); //然后这里调用service,通过id取得需要的文章article   
  12.     env.setVariable("article", DEFAULT_WRAPPER.wrap(article)); /*使用env.setVariable方法设置变量article(这个就是要返回给页面的数据),注意需要使用freemarker中的静态成员变量DEFAULT_WRAPPER把article处理一下 */  
  13.     body.render(env.getOut()); //最后使用body.render(env.getOut())将数据交给模版页面    
  14.     }  
  15. }  



然后编写Controller

  1. @RequestMapping(value = "/document/getArticle.action")  
  2. public String getColumn( ModelMap root) throws Exception {  
  3.     root.put(“article_d”, new ArticleDirective()); /*把标签加进去,我的标签名为article_d,方便区分数据,注意命名不要与变量名一样,否则会出问题 */  
  4.     return article;  
  5. }  


那么article.ftl这样编写:
  1. <pre name="code" class="html"><!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. </head>  
  5. <body>  
  6.     <@article articleId = 5> <#-- 使用自定义标签,传入的参数与自定义标签类保持一致 -->  
  7.     文章的标题是${article.title},文章的内容是${article.content}  
  8.     </@article>              
  9. </body>  
  10. </html>  



那么访问getArticle.action则跳转到页面输出结果:文章的标题是:...,文章的内容是...。如果我访问这个页面时需要输出第六篇文章,那么只需要在模版上把articleId设定为6就可以啦。

好了,这就是最简单的整合流程了。微笑

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多