1.起因
近期Chinese office的同事需要我帮忙写一个管理Test Case和Test Task的Web小应用,正好和印度合作开发的网管是基于ExtJS+Spring+Hibernate的模式。考虑到Test Team对于编码方面的掌握没有我们熟悉,决定去掉Hibernate重新搞一个Frame给她们用。不过由于在H3C荒废了太久的时间,很多技术都是知其然,不知其所以然。在这里用F开头的单词问候H3C一下。哈哈。
2.探索
好了,先从网络上找个Spring例子吧。我发现这个网站不错,http://www.vaannila.com/里面很多例子可以参考。并且有打包好的例子下载。废话不多说,先下载一个Example10看看吧。首先是web.xml配置文件,没有什么特别的。就只有一个DispatchServlet的配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>SpringExample10</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
dispatcher-servlet.xml
然后是dispatcher-servlet.xml。其中dispatcher是上面servelet的名字。这个要对应好。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
<bean name="/user/*.htm" class="com.vaannila.web.UserController" />
</beans>
UserController.java
其中的UserController.java代码如下。其中的add,delete都是方法字。
package com.vaannila.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
public class UserController extends MultiActionController {
public ModelAndView add(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("Add method called");
return new ModelAndView("user", "message", "Add method called");
}
public ModelAndView remove(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("Remove method called");
return new ModelAndView("user", "message", "Remove method called");
}
}
随便创建一个web工程,把这些代码拷贝进去,覆盖原来的*.xml文件即可。启动tomcat即可运行。
问题
1.UserController 的各种方法返回一个ModelandView对象,其中第一个参数表示对应的视图名称,这个很重要,请看Dispatcher-servelet.xml里面还有一个<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />,配置,指明了这些JSP文件的路径在哪里。比如你返回一个 ModelAndView("user", "message", "Remove method called"); 那么系统就会主动到web-inf/jsp目录下面找名字开头是use.jsp的文件来展示这些内容。.
User.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Success Page</title>
</head>
<body>
${message}
</body>
</html>
好了,至此如果只是Spring,就一切Okay了,Spring can work well now.
ExtJS + Spring
如果需要支持ExtJS, 就需要对这些进行一下改进。当然我的改进并不是完美的,毕竟本人不是乔布斯那种大牛。
修改web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>SpringExample10</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Context configuration -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/ContextConfiguration.xml
</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
增加绿色部分。指定一个Context,当然我不确定是一定需要这么干。毕竟是为以后的扩张留下好的接口嘛。
ContextConfiguration.xml
这个ContextConfiguration.xml就是上面增加的配置文件里面的内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<context:component-scan base-package="my.package"/>
<bean id="xmlFileViewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order">
<value>1</value>
</property>
</bean>
</beans>
红色部分很重要。如果不写这个,下面的views.xml里面的东东就不会起作用!!!!
增加一个新文件views.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView"/>
</beans>
大家都知道ExtJS会采用Json来传递Ajax信息。这里就是配置Json视图的,注意bean name = 'JsonView'这里。
好, 最后给个例子,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Hello World Window Example</title>
<link rel="stylesheet" type="text/css" href="ext-3.3.1/resources/css/ext-all.css" />
<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="ext-3.3.1/adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="ext-3.3.1//ext-all.js"></script>
<script language="javascript" src="hello.js"></script>
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<style type="text/css">
.x-panel-body p {
margin:10px;
font-size:12px;
}
</style>
</head>
<body>
<script type="text/javascript" src="../shared/examples.js"></script><!-- EXAMPLES -->
<h1>Hello World Window</h1>
<p>This example shows how to create a very simple Window with "autoTabs" from existing markup.</p>
<input type="button" id="show-btn" value="Hello World" /><br /><br />
<p>Note that the js is not minified so it is readable. See <a href="hello.js">hello.js</a> for the full source code.</p>
<div id="hello-win" class="x-hidden">
<div class="x-window-header">Hello Dialog</div>
<div id="hello-tabs">
<!-- Auto create tab 1 -->
<div class="x-tab" title="Hello World 1">
<p>Hello...</p>
</div>
<!-- Auto create tab 2 -->
<div class="x-tab" title="Hello World 2">
<p>... World!</p>
</div>
</div>
</div>
</body>
</html>
上面的HTML不重要,重要的是JS脚本
/*!
* Ext JS Library 3.3.1
* Copyright(c) 2006-2010 Sencha Inc.
* licensing@sencha.com
* http://www.sencha.com/license
*/
Ext.onReady(function(){
var win;
var button = Ext.get('show-btn');
button.on('click', function(){
// create the window on the first click and reuse on subsequent clicks
if(!win){
win = new Ext.Window({
applyTo:'hello-win',
layout:'fit',
width:500,
height:300,
closeAction:'hide',
plain: true,
items: new Ext.TabPanel({
applyTo: 'hello-tabs',
autoTabs:true,
activeTab:0,
deferredRender:false,
border:false
}),
buttons: [{
text:'Submit',
disabled:true
},{
text: 'Close',
handler: function(){
Ext.Ajax.request({
url: 'user/add.htm',
method: 'POST',
success:function(result, request){
alert('good');
},
failure: function(form, action){
alert('fuck');
} ,
scope: this
});
}
}]
});
}
win.show(this);
});
});
请注意红色部分,当button被click的时候会触发这个方法。那么我们会send一个ajax request到URL 'user/add.htm, 这里的时候请看dispatcher-servlet.xml里面的配置,当然这个add.htm并不存在, 就是一个标志。程序会自动到UserController里面去寻找add方法!!!
当然,add方法也对应做一点点点的修改即可。Just look below:
public ModelAndView add(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("Add method called");
return new ModelAndView("jsonView", "message", "Add method called");
}
看到没有,这里的jsonView就是上面在配置文件里面写道的bean的名字。写错了就搞不定了!!!
最后一点就是在/WEB-INF/lib里面放入足够的jar文件,一旦缺少某些jar文件,就不能保证一定能够Okay了。compile的时候不会出问题,当时Run的时候就会各种诡异的现象出现了。