zoukankan      html  css  js  c++  java
  • velocity模板引擎学习(2)-velocity tools 2.0

    使用velocity后,原来的很多标签无法使用了,必须借助velocity tools来完成,目前velocity tools最新版本是2.0,下面是velocity tools的一些注意事项:

    1. 与Spring MVC 3.x/4.x的集成问题

    Spring 3.x/4.x只支持1.3.x的velocity tools,要使用2.0必须自己扩展VelocityToolboxView类

     1 package org.springframework.web.servlet.view.velocity;
     2 
     3 import java.util.Map;
     4 
     5 import javax.servlet.http.HttpServletRequest;
     6 import javax.servlet.http.HttpServletResponse;
     7 
     8 import org.apache.velocity.context.Context;
     9 import org.apache.velocity.tools.Scope;
    10 import org.apache.velocity.tools.ToolManager;
    11 import org.apache.velocity.tools.view.ViewToolContext;
    12 import org.springframework.web.servlet.view.velocity.VelocityToolboxView;
    13 
    14 public class VelocityToolbox2View extends VelocityToolboxView {
    15     @Override
    16     protected Context createVelocityContext(Map<String, Object> model,
    17             HttpServletRequest request, HttpServletResponse response)
    18             throws Exception {// Create a
    19                                 // ChainedContext
    20                                 // instance.
    21         ViewToolContext ctx;
    22 
    23         ctx = new ViewToolContext(getVelocityEngine(), request, response,
    24                 getServletContext());
    25 
    26         ctx.putAll(model);
    27 
    28         if (this.getToolboxConfigLocation() != null) {
    29             ToolManager tm = new ToolManager();
    30             tm.setVelocityEngine(getVelocityEngine());
    31             tm.configure(getServletContext().getRealPath(
    32                     getToolboxConfigLocation()));
    33             if (tm.getToolboxFactory().hasTools(Scope.REQUEST)) {
    34                 ctx.addToolbox(tm.getToolboxFactory().createToolbox(
    35                         Scope.REQUEST));
    36             }
    37             if (tm.getToolboxFactory().hasTools(Scope.APPLICATION)) {
    38                 ctx.addToolbox(tm.getToolboxFactory().createToolbox(
    39                         Scope.APPLICATION));
    40             }
    41             if (tm.getToolboxFactory().hasTools(Scope.SESSION)) {
    42                 ctx.addToolbox(tm.getToolboxFactory().createToolbox(
    43                         Scope.SESSION));
    44             }
    45         }
    46         return ctx;
    47     }
    48 }
    View Code

    注:31行tm.configure(getServletContext().getRealPath(getToolboxConfigLocation()));这里,在某些容器,比如weblogic中,getRealPath可能取不到值,可改成

    getResource试试

    然后在spring mvc的servlet配置文件中参考如下设置:

     1 <bean
     2                     class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
     3                     <property name="order" value="0" />
     4                     <property name="cache" value="true" />
     5                     <property name="prefix" value="" />
     6                     <property name="suffix" value=".vm" />
     7                     <property name="toolboxConfigLocation" value="/WEB-INF/toolbox.xml" />                    
     8                     <property name="contentType" value="text/html;charset=UTF-8" />
     9                     <property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityToolbox2View"></property>
    10                 </bean>
    View Code

    2. 如何获取当前应用的contextPath

    1     <tool>
    2         <key>link</key>
    3         <scope>request</scope>
    4         <class>org.apache.velocity.tools.view.LinkTool</class>
    5     </tool>

    借助velocity-tools的LinkTool类,在velocity中直接用${link.contextPath}即可得到当前的contextPath

    3、如何获取url参数

    1     <tool>
    2         <key>params</key>
    3         <scope>request</scope>
    4         <class>org.apache.velocity.tools.view.ParameterTool</class>
    5     </tool>

    然后就可以用类似$params.returnUrl,来获取类似 http://xxx.com/login?returnUrl=abc 中的 abc部分

    4、如何与Spring-Security集成

    1 <sec:authorize access="isAnonymous()">
    2 ...
    3     </sec:authorize>
    View Code

    之类的标签无法在velocity中使用,而velocity-tools中也未提供相应的支持,在老外的一篇博客上,看到了解决方案:

     1 package com.cnblogs.yjmyzz.utils;
     2 
     3 import java.util.Collection;
     4 import java.util.HashSet;
     5 import java.util.Set;
     6 import org.springframework.security.core.GrantedAuthority;
     7 import org.springframework.security.core.context.SecurityContextHolder;
     8 import org.springframework.security.core.userdetails.UserDetails;
     9 
    10 public class VelocitySecurityUtil {
    11 
    12     public static String getPrincipal() {
    13 
    14         Object obj = SecurityContextHolder.getContext().getAuthentication()
    15                 .getPrincipal();
    16 
    17         if (obj instanceof UserDetails) {
    18             return ((UserDetails) obj).getUsername();
    19         } else {
    20             return "anonymous";
    21         }
    22     }
    23 
    24     public static boolean isAuthenticated() {
    25         return !getPrincipal().equals("anonymous");
    26     }
    27 
    28     public static boolean allGranted(String[] checkForAuths) {
    29         Set<String> userAuths = getUserAuthorities();
    30         for (String auth : checkForAuths) {
    31             if (userAuths.contains(auth))
    32                 continue;
    33             return false;
    34         }
    35         return true;
    36     }
    37 
    38     public static boolean anyGranted(String[] checkForAuths) {
    39         Set<String> userAuths = getUserAuthorities();
    40         for (String auth : checkForAuths) {
    41             if (userAuths.contains(auth))
    42                 return true;
    43         }
    44         return false;
    45     }
    46 
    47     public static boolean noneGranted(String[] checkForAuths) {
    48         Set<String> userAuths = getUserAuthorities();
    49         for (String auth : checkForAuths) {
    50             if (userAuths.contains(auth))
    51                 return false;
    52         }
    53         return true;
    54     }
    55 
    56     private static Set<String> getUserAuthorities() {
    57         Object obj = SecurityContextHolder.getContext().getAuthentication()
    58                 .getPrincipal();
    59         Set<String> roles = new HashSet<String>();
    60         if (obj instanceof UserDetails) {
    61             @SuppressWarnings("unchecked")
    62             Collection<GrantedAuthority> gas = (Collection<GrantedAuthority>) ((UserDetails) obj)
    63                     .getAuthorities();
    64             for (GrantedAuthority ga : gas) {
    65                 roles.add(ga.getAuthority());
    66             }
    67         }
    68         return roles;
    69     }
    70 
    71 }
    View Code

    然后修改配置:

     1     <bean id="velocitySecurityUtil" class="com.cnblogs.yjmyzz.utils.VelocitySecurityUtil" />
     2 
     3     <bean
     4         class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
     5         <property name="order" value="1" />
     6         ...
     7         <property name="viewResolvers">
     8             <list>
     9                 <bean
    10                     class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
    11                     <property name="order" value="0" />
    12                     ...
    13                     <property name="attributesMap">
    14                         <map>
    15                             <entry key="sec">
    16                                 <ref bean="velocitySecurityUtil" />
    17                             </entry>
    18                         </map>
    19                     </property>
    20 
    21                 </bean>
    22                 ...
    View Code

    页面就能用了:

    1     #if(${sec.authenticated}) 
    2     ...
    3     #end
    View Code

    注:这个思路也可以用于实现自己的Velocity-Tools类,比如我们创建了一个自己的RequestUtil类

     1 package com.cnblogs.yjmyzz.utils;
     2 import javax.servlet.http.HttpServletRequest;
     3 public class RequestUtil{
     4 
     5     /**
     6      * 获取当前请求的基地址(例如:http://localhost:8080/ctas/xxx.do 返回 http://localhost:8080/ctas/)
     7      *
     8      * @param request
     9      * @return
    10      */
    11     public static String getBaseUrl(HttpServletRequest request) {
    12         return request.getRequestURL().substring(0,
    13                 request.getRequestURL().indexOf(request.getContextPath()) + request.getContextPath().length()) + "/";
    14     }
    15 
    16 }
    View Code

    然后在配置里,加上

     1     <bean id="requestUtil" class="com.cnblogs.yjmyzz.utils.RequestUtil"/>
     2 
     3     <bean
     4             class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
     5         <property name="order" value="1"/>
     6        ...
     7         <property name="viewResolvers">
     8             <list>
     9                 ...
    10                 <bean
    11                         class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
    12                     <property name="order" value="0"/>
    13                  ...
    14                     <property name="viewClass"
    15                               value="com.cnblogs.yjmyzz.utils.VelocityToolbox2View"></property>
    16                     <property name="attributesMap">
    17                         <map>
    18                           ...
    19                             <entry key="req">
    20                                 <ref bean="requestUtil"/>
    21                             </entry>
    22                         </map>
    23                     </property>
    24                 </bean>
    25               ...
    26     </bean>
    View Code

     vm页面这样用

    1 #*取得页面链接基地址*#
    2 #macro(baseHref)${req.getBaseUrl($request)}#end
    3 ...
    4 <base href="#{baseHref}">
    5 ...
    6 <script type="text/javascript">
    7     var baseHref = "#{baseHref}";
    8 </script>
    9 ...
    View Code

    顺便提一句:网上有一堆文章和教程,让你在toolbox.xml中添加类似

    1     <tool>
    2         <key>req</key>
    3         <scope>request</scope>
    4         <class>com.cnblogs.yjmyzz.utils.RequestUtil</class>
    5     </tool>
    View Code

    在Spring MVC4 + Velocity Tools2的组合下,然而,这并没有什么用,在Spring MVC4 + Velocity-Tools2下,已经不好使了。

    最后,Velocity还允许自定义标签(也有人称为自定义指令),支持开发人员定义自己的标签,比如#YourDirective,详情可参考:

    编写自定义的 Velocity 指令 

  • 相关阅读:
    P1219 [USACO1.5]八皇后 Checker Challenge 深度搜索 标记 回溯
    P2036 [COCI2008-2009#2] PERKET 深度搜索 暴力
    20201122 赛事纪录
    P4447 [AHOI2018初中组]分组 贪心
    P4995 跳跳! 贪心
    P1434 [SHOI2002]滑雪 记忆化搜索,深度搜索,动态规划
    leetcode(42)接雨水
    数据结构与算法的总纲
    leetcode(84)柱状图中最大的矩形
    leetcode(45)跳跃游戏
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/4188749.html
Copyright © 2011-2022 走看看