目前流行的三大页面视图神器是:老牌大哥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');"> 删除</a></td>
</tr>
#end
</table>
</div></td>
<td>接口名: <input type="text" name="interfaceName"
id="interfaceName" style="width: 400px" /> <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>