spring mvc集成velocity使用

时间:2022-11-24 15:41:58

  目前流行的三大页面视图神器是:老牌大哥jsp、后起之秀freemarker和velocity。这里不详细比较这三者的优劣,总体来说,jsp是标配,但后面两个更严格的执行了视图与业务的分离,页面里是不允许出现java代码的。velocity是模板语言,更强调复用,性能也更好一些,velocity就是速度的意思。freemarker的集成看spring mvc集成freemarker使用

  目前流行的web框架是spring mvc,作为整合老手spring可以无缝接洽上面三个视图解析器。这里着重看下velocity怎么在spring mvc里用。

  首先定义spring的web配置文件:

spring-mvc.xm

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd ">

    <context:component-scan base-package="com.wulinfeng.test.testpilling" />
    <mvc:annotation-driven />
    
    <!-- velocity配置 --> 
    <bean id="velocityConfiger"  class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">  
        <property name="resourceLoaderPath" value="/" />  
        <property name="configLocation" value="classpath:velocity.properties" />  
    </bean>  
      
    <!-- 配置视图的显示 -->  
    <bean id="ViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">  
        <property name="cache" value="true" />  
        <property name="prefix" value="/" /><!-- 视图文件的前缀,即存放的路径 -->  
        <property name="suffix" value=".html" /><!-- 视图文件的后缀名 -->
        <property name="dateToolAttribute" value="date" /><!--日期函数名称-->  
        <property name="numberToolAttribute" value="number" /><!--数字函数名称-->  
        <property name="contentType" value="text/html;charset=UTF-8" />  
        <property name="exposeSpringMacroHelpers" value="true" /><!--是否使用spring对宏定义的支持-->  
        <property name="exposeRequestAttributes" value="true" /><!--是否开放request属性-->  
        <property name="requestContextAttribute" value="rc"/><!--request属性引用名称-->  
    </bean> 
</beans>

velocity.properties

#encoding
input.encoding=UTF-8
output.encoding=UTF-8
contentType=text/html;charset=UTF-8  
  
#autoreload when vm changed  
file.resource.loader.cache=false
file.resource.loader.modificationCheckInterval=1
velocimacro.library.autoreload=false

  配置好了视图解析器后,我们来看下怎么在页面中用,分别列出controller和页面:

package com.wulinfeng.test.testpilling.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.wulinfeng.test.testpilling.service.TestPillingService;
import com.wulinfeng.test.testpilling.util.PropertiesConfigUtil;

@Controller
public class TestPillingController
{
    /** 主页 */
    private static final String HOME_PAGE = PropertiesConfigUtil.getProperty("homepage");
    
    @Autowired
    private TestPillingService testPillingService;
    
    /**
     * 加载主页
     *
     * @author wulinfeng
     * @param model
     * @return
     */
    @RequestMapping(value = "/home.html", method = RequestMethod.GET)
    public String getMethodContent(Model model)
    {
        testPillingService.initialize(model);
        return HOME_PAGE;
    }
    
    /**
     * 获取单个测试桩接口内容
     *
     * @author wulinfeng
     * @param method
     * @return
     */
    @RequestMapping(value = "/getMethod/{method}", method = RequestMethod.GET)
    public @ResponseBody String getMethodContent(@PathVariable("method") String method)
    {
        return testPillingService.getMethodContent(method);
    }
    
    /**
     * 新增测试桩
     *
     * @author wulinfeng
     * @param method
     * @param requestBody
     * @return
     */
    @RequestMapping(value = "/editMethod/{method}", method = RequestMethod.POST)
    public @ResponseBody void editMethodContent(@PathVariable("method") String method, @RequestBody String requestBody)
    {
        testPillingService.editMethodContent(method, requestBody);
    }
    
    /**
     * 删除测试桩
     *
     * @author wulinfeng
     * @param method
     */
    @RequestMapping(value = "/deleteMethod/{method}", method = RequestMethod.GET)
    public @ResponseBody void deleteMethodContent(@PathVariable("method") String method)
    {
        testPillingService.deleteMethodContent(method);
    }
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试桩配置页面</title>
</head>
<body>
    <form id="interfaceForm">
        <h2 align="center">
            <font color="#FF0000">测试桩配置</font>
        </h2>
        <table
            style="width: 1200px; height: 600px; margin-left: 5%; margin-top: 30px;"
            border="2px" bordercolor="gray" cellspacing="0px" cellpadding="5px">
            <tr height="10%">
                <td rowspan="3" width="32%" valign="top" align="center"><font
                    size="4pt" color="black">接口名称:</font><br /> <br />
                    <div name="interfaceNames" id="interfaceNames"
                        style="border: solid 2px pink; width: 350px; height: 520px; overflow: auto;">
                        <table>
                            #foreach($method in $methodKeys)
                            <tr valign="top" style="height: 25px;">
                                <td align="center" width="150px"><a
                                    onclick="getMethodContent('$method');">$method</a></td>
                                <td width="100px" align="left"><a
                                    style="text-decoration: none;"
                                    onclick="deleteInterfaceEntity('$method');">&nbsp;删除</a></td>
                            </tr>
                            #end
                        </table>
                    </div></td>
                <td>接口名: <input type="text" name="interfaceName"
                    id="interfaceName" style="width: 400px" /> &nbsp;&nbsp;&nbsp; <input
                    type="button" value="新增/修改" onclick="generateInterfaceEntity();" /></td>
            </tr>
            <tr>
                <td><font size="4pt" color="black"> 接口报文:</font><br /> <br />
                    <textarea name="interfaceBody" id="interfaceBody"
                        style="width: 700px; height: 450px; margin-left: 50px;">
                    </textarea></td>
            </tr>
        </table>
    </form>
</body>

<script type="text/javascript">
    var xmlHttp;

    //创建一个xmlHttpRequest对象
    window.onload = function createxmlHttp() {
        try {
            //尝试创建 xmlHttpRequest 对象,除 IE 外的浏览器都支持这个方法。  
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                //使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.xmlHttp)。  
                xmlHttp = ActiveXObject("Msxml12.XMLHTTP");
            } catch (e1) {
                try {
                    //使用较老版本的 IE 创建 IE 兼容的对象(Microsoft.xmlHttp)。  
                    xmlHttp = ActiveXObject("Microsoft.XMLHTTP");
                } catch (e2) {
                    flag = false;
                }
            }
        }

        //判断是否成功的例子:  
        if (!xmlHttp) {
            alert("creat XMLHttpRequest Object failed.");
        }
    }

    //调用http接口获取接口内容
    function getMethodContent(method) {
        url = "/getMethod/" + method;
        xmlHttp.open("GET", url, true);
        xmlHttp.onreadystatechange = showContent;
        document.getElementById("interfaceName").value = method; //将接口名放入html指定div中
        xmlHttp.send();
    }

    //回调函数,显示http响应结果
    function showContent() {
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.status == 200) {
                var text = xmlHttp.responseText; //这里获得服务器返回的数据
                document.getElementById("interfaceBody").innerHTML = text; //将数据放入html指定div中
            } else {
                alert("response error code:" + xmlHttp.status);
            }
        }
    }

    //删除接口
    function deleteInterfaceEntity(method) {
        url = "/deleteMethod/" + method;
        xmlHttp.open("GET", url, true);
        xmlHttp.onreadystatechange = showActionResult;
        xmlHttp.send();
    }

    //新增、编辑接口
    function generateInterfaceEntity() {
        url = "/editMethod/" + document.getElementById("interfaceName").value;
        xmlHttp.open("POST", url, true);
        xmlHttp.setRequestHeader("Content-type",
                "application/json;charset=UTF-8");
        xmlHttp.onreadystatechange = showActionResult;
        xmlHttp.send(document.getElementById("interfaceBody").innerHTML);
    }

    //回调函数,显示action操作结果,刷新页面
    function showActionResult() {
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.status == 200) {
                alert("operation success!");
                window.location.reload();
            } else {
                alert("operation failed! response error code:" + xmlHttp.status);
            }
        }
    }
</script>
</html>

   下面是service类设置数据的方法

    /**
     * 加载测试桩接口列表
     *
     * @author wulinfeng
     * @param model
     */
    public void initialize(Model model)
    {
        model.addAttribute("methodKeys", methodMap.keySet());
    }

  这里页面虽然是html,实际上就是velocity,注意看上面的配置<property name="suffix" value=".html" />,最后maven的pom文件里注意jar引入:

		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.7</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity-tools</artifactId>
			<version>2.0</version>
			<scope>compile</scope>
		</dependency>