项目中我们常常遇到这种需求——页面部分刷新。比如:加入用户,转到加入用户页面时,页面自己主动载入了全部部门。
完整流程:选择所属部门,填写username和password,点击“注冊”
填写username后,须要马上检查数据库是否存在此username,怎样在不刷新页面的情况下实现此效果?
但看上面提出的问题并不难。情况非经常见,都知道使用ajax实现。可是怎样在struts中自己定义结果集来实现ajax——这是这篇博客的重点。
(注:servlet要么转发要么重定向。struts2能够自己定义结果集)
转发、重定向、action2action都会使页面刷新,满足不了页面无刷新的需求,因此,能够自定义一个结果集来解决(通过此结果集把server端(action)的数据回调到client)。
工具:MyEclipse8.5、tomcat6.0.39
一。步骤:
1,创建一个名称为Struts+AjaxResult的Web项目
2,导入Struts相关包
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGFueHVlbWluMTIzNDU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
3,配置web.xml文件
4,创建PoJo类——User.java
5,创建Action基类和子Action类——BaseAction、UserAction.java
6,创建自己定义结果集——AjaxResult.java
7,配置Struts.xml文件
8,创建页面——add.jsp
9,创建js文件——user_add.js
(注:还需引入jquery.js文件)
----web.xml:配置文件(注:配置Struts2的核芯过滤器)
<span style="font-family:KaiTi_GB2312;font-size:18px;"><? xmlversion="1.0" encoding="UTF-8"?>
<web-appversion="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 配置Struts2的核心的过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app></span>
----User.java:用户实体类
<span style="font-family:KaiTi_GB2312;font-size:18px;">importjava.io.Serializable;
public class Userimplements Serializable{
private Long uid;//用户id
private String username;//用户名
private String password;//密码 //*********get/set方法*********************************************
publicLong getUid() {
returnuid;
} publicvoid setUid(Long uid) {
this.uid= uid;
} publicString getUsername() {
returnusername;
} publicvoid setUsername(String username) {
this.username= username;
} publicString getPassword() {
returnpassword;
} publicvoid setPassword(String password) {
this.password= password;
} }</span>
----BaseAction.java:抽象Action类,封装公共内容
<span style="font-family:KaiTi_GB2312;font-size:18px;">importjava.lang.reflect.ParameterizedType; importcom.opensymphony.xwork2.ActionSupport;
importcom.opensymphony.xwork2.ModelDriven; /**
* 这里封装一些共用的内容
* @author Administrator
*
*/
public classBaseAction<T> extends ActionSupport implements ModelDriven<T>{
privateClass classt;
privateT t; publicstatic final String ADDUI = "addUI";
publicString addUI = ADDUI; publicBaseAction(){
try{
ParameterizedTypetype = (ParameterizedType)this.getClass().getGenericSuperclass();
this.classt= (Class)type.getActualTypeArguments()[0];
this.t= (T)this.classt.newInstance();
}catch(Exceptione){
e.printStackTrace();
}
} publicT getModel() {
//TODO Auto-generated method stub
returnthis.t;
}
}</span>
----UserAction.java:用户模块处理 Action
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="color:#333333;">importcn.itcast.oa0909.domain.User;
importcn.itcast.oa0909.struts2.action.base.BaseAction;
importcom.opensymphony.xwork2.ActionContext; publicclass UserAction extendsBaseAction<User>{ /**
* 跳转到加入用户页面
* @return
*/
publicString addUI(){
returnaddUI;
}
/**
* 校验username是否存在
* @return
*/
publicString checkUserName(){ if("学敏".equals(this.getModel().getUsername())){//假设输入的username为"学敏"
ActionContext.getContext().getValueStack().push("该username已经存在");//把数据压入栈顶
}else{//假设输入的username就不是“学敏”
ActionContext.getContext().getValueStack().push("该username能够使用");//把数据压入栈顶
} returnSUCCESS;
} }</span></span>
----AjaxResult.java:自己定义结果集(注:通过此结果集把server端(action)的数据回调到client)
<span style="font-family:KaiTi_GB2312;font-size:18px;">importjavax.servlet.http.HttpServletResponse; importorg.apache.struts2.ServletActionContext; importcom.opensymphony.xwork2.ActionContext;
importcom.opensymphony.xwork2.ActionInvocation;
importcom.opensymphony.xwork2.Result; public classAjaxResult implements Result{
publicvoid execute(ActionInvocation invocation) throws Exception {
HttpServletResponseresponse = ServletActionContext.getResponse();
response.setCharacterEncoding("utf-8");//处理中文乱码问题
String message =ActionContext.getContext().getValueStack().peek().toString();//得到栈顶元素
response.getWriter().print(message);//将得到的栈顶元素返回到client
}
}</span>
----struts.xml:Struts配置文件
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?xmlversion="1.0" encoding="UTF-8"?>
<!DOCTYPE strutsPUBLIC
"-//ApacheSoftware Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<!-- 配置文件改了以后不用又一次启动 -->
<constant name="struts.devMode"value="true"/>
<constantname="struts.ui.theme" value="simple"/> <includefile="struts/struts-user.xml"></include> <!-- 配置自己定义结果集-->
<packagename="ajax-default" extends="struts-default">
<result-types>
<result-typename="ajax"class="cn.itcast.oa0909.result.AjaxResult"></result-type>
</result-types>
</package>
</struts>
</span>
----struts-user.xml
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?xmlversion="1.0" encoding="UTF-8"?>
<!DOCTYPE strutsPUBLIC
"-//ApacheSoftware Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts> <!--继承Struts-default结果集 -->
<package name="user"namespace="/" extends="struts-default">
<actionname="userAction_*" method="{1}"class="cn.itcast.oa0909.struts2.action.UserAction">
<resultname="addUI">WEB-INF/jsp/user/add.jsp</result>
</action>
</package> <!-- 继承自己定义结果集——ajax-default(在struts.xml文件里已配置) -->
<package name="userjson"namespace="/" extends="ajax-default">
<actionname="userJSONAction_*" method="{1}"class="cn.itcast.oa0909.struts2.action.UserAction">
<resulttype="ajax"></result>
</action>
</package> </struts> </span>
----add.jsp:加入用户页面
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ pagelanguage="java" import="java.util.*"pageEncoding="UTF-8"%>
<scriptlanguage="javascript"src="${pageContext.request.contextPath}/js/jquery-1.4.2.js"></script>
<scriptlanguage="javascript"src="${pageContext.request.contextPath}/js/user_add.js"></script>
<html>
<head>
<title>用户信息</title>
<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<form action="userAction_add.action">
<table>
<tr><tdwidth="100">所属部门</td>
<td><selectname="departmentId" class="SelectStyle">
<optionvalue="0" selected="selected">请选择部门</option>
<optionvalue="7">总经理室</option>
<optionvalue="1">市场部</option>
<optionvalue="2">咨询部</option>
<optionvalue="3">招生部</option>
<optionvalue="4">教学部</option>
<optionvalue="5">后勤部</option>
</select>
</td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text"name="username"/><labelid="message"></label></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password"name="password"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit"value="注冊"/></td>
</tr> </table>
</form>
</body> </html></span>
(注:如果这里的所属部门中的数据是页面载入时从数据库中读取的,而不是如上所看到的写死的)
页面效果:
所属部门下拉框展开。例如以下所看到的:
-----user_add.js:加入用户页面所需js
<span style="font-family:KaiTi_GB2312;font-size:18px;">var user = {
//初始化事件
inintEvent: function(){
$("input[name='username']").unbind("blur");
$("input[name='username']").bind("blur",function(){//name值为"username"的文本框失去焦点触发的函数
user.checkUser($(this).val());//调用检查用户函数(校验用户名是否存在)
});
},
/**
* 校验用户名是否存在
*/
checkUser:function(username){
var a ="a";
var parameter = {//參数:用户名
username:username
}; /**
*userJSONAction_checkUserName.action:请求地址
* parameter:參数
*function(data){}:回调函数
*/
$.post("userJSONAction_checkUserName.action",parameter,function(data){
$("#message").text(data);//将server返回的值赋给id="message"的label提示框,并显示
if(data=="该用户名能够使用"){
$("#message").css("color","blue");//设置提示文字的颜色
}else{
$("#message").css("color","red");//设置提示文字的颜色
}
}); }
};
//页面载入时执行
$().ready(function(){
user.inintEvent();//页面载入时,调用初始化事件
</span>
二,执行
输入地址:http://localhost:8080/Struts2+AjaxResult/userAction_addUI.action,显演示样例如以下页面
username输入“学敏”。数据库中已经存在了此username。则当鼠标离开username文本框(即。username文本框失去焦点)时(注:此处为ajax请求,它的处理过程,和应用的技术点为本博客解说的重点)。就会提示“该用户已经存在”。username输入“张三那”,数据库中不存在,则提示“该username能够使用”
三,总结
自己定义结果集的缺点:
这样自己定义的结果集,写死了,不能做到client须要什么数据就传什么数据。
如,UserAction中的代码:
ActionContext.getContext().getValueStack().push("该username已经存在");//把数据压入栈顶
——把client须要的数据都要压入栈顶
AjaxResult中的代码:
String message =ActionContext.getContext().getValueStack().peek().toString();//得到栈顶元素
response.getWriter().print(message);//将得到的栈顶元素返回到client
——获取栈顶的元素,再通过
response.getWriter().print()语句将的到的栈顶元素返回到client;
那么问题来了。假设我须要的数据添加了。怎么办?毋庸置疑。在UserAction
中将添加的数据压入栈顶,还要在AjaxResult中依次获取数据,再通过
response.getWriter().print()依次返回,也就是会说此AjaxResult与UserAction要一一相应,必须写死在程序里。不灵活,不能做到client须要什么数据就传什么数据。
另外另一个问题,假设其它业务。比方“部门管理”模块的一个功能也须要从server端返回数据到client,那是不是还要再写一个自己定义结果集,AjaxResult怎样做到复用。能不能做到复用,这是个问题。
基于以上问题。下篇博客介绍——json类型的结果集——JSON插件是Struts2的Ajax插件,通过利用JSON插件,同意开发人员以很灵活的方式开发AJAX应用。
版权声明:本文博主原创文章。博客,未经同意不得转载。