最近研究了下ajax 并把ajax方法做了简单的封装,可以应用于各种web应用中:
一,在struts2.x中应用
首先,创建jsp页面mytest.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript">
//用于响应按钮点击事件
function testAjax(){
//getServerTime();
// var param="name=xumian&age=24";//字符形式的参数
var param={"name":"xumian","age":"24"}//json格式的参数
var ajax=new Ajax("ajaxJsonObj.action",param);
var tmp=ajax.getResult("afertAjax");
//var tmp=ajax.getResult(); //直接返回结果,不回调函数
//alert(tmp)
//var ajax=new Ajax("testJson.action","name=xumian");
//var tmp=ajax.getResult();
//alert(tmp.name);
}
//后台响应后回调函数
function afertAjax(obj){
alert(obj[0].name);
}
//ajax 对象
var Ajax=function(url,params){
this.url=url;
this.args="";
this.parseUrl=function(){//构造ajax 的Url
if(params instanceof Object){//json对象格式的参数
var count=0;
for(var item in params){
if(count===0){
this.args="?"+item+"="+params[item];
}else{
this.args=this.args+"&"+item+"="+params[item];
}
count=count+1;
}
}else if(params!==""&¶ms!==undefined){
this.args="?"+params;
}
this.url=this.url+this.args;
return this.url;
};
this.createXMLHttp=function(){//创建XMLHttp对象
var xmlhttp=null;
try {
xmlhttp = new XMLHttpRequest();
}catch (e) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
};
this.getResult=function(){//调用ajax并返回结果
return this.exeAjax("", false);
};
this.getResult=function(callBack_method){//调用ajax并回调callBack_method 方法
return this.exeAjax(callBack_method, false);
};
this.exeAjax=function(callback_method,isJson){
var xmlHttp=this.createXMLHttp();
xmlHttp.open("GET",this.parseUrl(),false);
xmlHttp.send(null);
if(xmlHttp.status=="200"){
if(callback_method === ""||callback_method===undefined){
try{
return eval("("+xmlHttp.responseText+")");//返回json 类型的结果
}catch(e){
return xmlHttp.responseText;//返回字符串形式的结果
}
}
var method="";
try{
method=callback_method+"("+xmlHttp.responseText.trim()+")";
return eval(method);
}catch(e){
method=callback_method+"('"+xmlHttp.responseText.trim()+"')";
return eval(method);
}
}else{
return "error";
}
};
};
</script>
</head>
<body>
<div id="mm" style="width:120px;">
<input type="button" value="testAjax" onclick="testAjax()"/>
</div>
</body>
</html>
然后,创建action TestAction.java:
package com.test.action;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.test.entity.Student;
import com.test.util.JsonData;
public class TestAction {
private String name;
private String password;
public String execute() {
System.out.println("test name:" + name);
System.out.println("password:" + password);
return "success";
}
//以struts的方式返回json形式的结果
public String testJsonType(){
this.name="xumian";
return "success";
}
// 返回系统时间
public String getServerTime() {
try {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
// 获取原始的PrintWriter对象,以便输出响应结果,而不用跳转到某个试图
HttpServletResponse response = ServletActionContext.getResponse();
// 设置字符集
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
// 直接输入响应的内容
out.println(sd.format(new Date()));
/** 格式化输出时间 **/
out.flush();
out.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;// 不需要跳转某个视图 因为上面已经有了直接输出的响应结果
}
//返回Json字符串
public String ajaxTest() {
try {
// 获取原始的PrintWriter对象,以便输出响应结果,而不用跳转到某个试图
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request=ServletActionContext.getRequest();
// 设置字符集
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
System.out.println("just a test" + name);
Student student = new Student();
student.setName("xum/" ^%$#@@!?'ian");
student.setAge(24);
student.setBooks(new String[] { "java", "Oracle", "C" });
Map<String, Integer> grads = new HashMap<String, Integer>();
grads.put("java", 99);
grads.put("C", 90);
student.setGrads(grads);
// 直接输入响应的内容
out.println(JsonData.toJsonObj(student));
out.flush();
out.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;// 不需要跳转某个视图 因为上面已经有了直接输出的响应结果
}
//返回json对象(数组)
public String ajaxTestJson() {
try {
// 获取原始的PrintWriter对象,以便输出响应结果,而不用跳转到某个试图
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request=ServletActionContext.getRequest();
// 设置字符集
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
System.out.println(request.getParameter("name"));
JSONArray ja=new JSONArray();
JSONObject jo=new JSONObject();
jo.put("name", "xumian");
jo.put("age", 24);
ja.add(jo);
// 直接输入响应的内容
out.println(ja);
out.flush();
out.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;// 不需要跳转某个视图 因为上面已经有了直接输出的响应结果
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
}
对象转json字符串工具类:
package com.test.util;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class JsonData {
@SuppressWarnings("unchecked")
public static String toJsonObj(Object obj) {
StringBuffer sb = new StringBuffer();
if (obj instanceof Object[]) {
sb.append("[");
Object[] values = (Object[]) obj;
for (int i = 0; i < values.length; i++) {
sb.append(toJsonObj(values[i]) + ",");
}
sb.append("]");
} else if (obj instanceof ArrayList) {
ArrayList list = (ArrayList) obj;
sb.append("[");
for (int i = 0; i < list.size(); i++) {
sb.append(toJsonObj(list.get(i)) + ",");
}
sb.append("]");
} else if (obj instanceof Set) {
Set vset=(Set)obj;
sb.append("[");
Iterator it1 = vset.iterator();
while(it1.hasNext()){
sb.append(toJsonObj(it1.next())+",");
}
sb.append("]");
} else if (obj instanceof Map) {
Map map =(HashMap)obj;
Set set =map.keySet();
Iterator it = set.iterator();
sb.append("{");
while(it.hasNext()){
Object keyObj=it.next();
try{
String key=keyObj.toString().replace("/"", "/////"");
sb.append("/""+key+"/":");
sb.append(toJsonObj(map.get(keyObj)));
sb.append(",");
}catch(Exception e){
sb.append("/""+keyObj+"/":");
sb.append(toJsonObj(map.get(keyObj)));
sb.append(",");
}
}
sb.append("}");
} else {
if (obj instanceof String||obj instanceof Integer
|| obj instanceof Double || obj instanceof Float
|| obj instanceof Long || obj instanceof Character
|| obj instanceof Byte || obj instanceof BigDecimal) {
sb.append("/"");
sb.append(obj.toString().replaceAll("/"", "/////""));
sb.append("/"");
} else {
if(obj==null){
return"/"null/"";
}else if("".equals(obj)){
return "/" /"";
}
StringBuffer objSB = new StringBuffer();
StringBuffer objSB2 = new StringBuffer();
String getMethod = "";
Class c = obj.getClass();
try {
objSB.append("{");
Method[] method=c.getMethods();
for(int i=0;i<method.length;i++){
String methodName=method[i].getName();
if(methodName.startsWith("get")
&&method[i].getParameterTypes().length==0
&&!"getClass".equals(methodName)
&&methodName.length()>3){
String field=methodName.substring(3);
field=field.replaceFirst(field.substring(0, 1), field.substring(0, 1).toLowerCase());
try{
Object objValue=c.getMethod(methodName, new Class[]{}).invoke(obj, new Object[]{});
objSB.append("/""+field+"/":");
objSB.append(toJsonObj(objValue));
objSB.append(",");
}catch(Exception nme){
System.out.println("[warn] no method of "+ getMethod + " in "+c.getName());
}
}
}
objSB.append("}");
sb.append(objSB.toString());
} catch (Exception e) {
objSB2.append("/"");
objSB2.append(obj.toString().replaceAll("/"", "/////""));
objSB2.append("/"");
sb.append(objSB2.toString());
}
}
}
return sb.toString().replaceAll(",}", "}").replaceAll(",]", "]");
}
}
配置struts.xml的action:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="demo" extends="struts-default">
<action name="test" class="com.test.action.TestAction">
<result name="success">
/pages/mytest.jsp
</result>
<result name="error">
/pages/error.jsp
</result>
</action>
<action name="ajax_*" class="com.test.action.TestAction" method="{1}">
<result>
/pages/mytest.jsp
</result>
</action>
<action name="ajaxObj" class="com.test.action.TestAction" method="ajaxTest">
<result>
/pages/mytest.jsp
</result>
</action>
<action name="ajaxJsonObj" class="com.test.action.TestAction" method="ajaxTestJson">
<result>
/pages/mytest.jsp
</result>
</action>
</package>
<!--这样配置的action 可以直接将action的属于以json形式返回,需引入json相关的jar包-->
<package name="json-login" extends="json-default" >
<action name="testJson" class="loginAction" method="testJsonType">
<result type="json"></result>
</action>
</package>
</struts>
这样就可以在struts2的架构中使用了;
二,在通用javaWeb项目中使用:
下面我介绍下如何不依赖任何mvc框架,直接在j2ee中使用ajax,实际上就是使用反射的基本方法直接调用指定类得指定方法而已:
创建一个javaweb项目,在WebRoot目录下创建一个目录Tools;
在刚才创建的Tools目录下建一个jsp文件:getAjax.jsp
<%@page contentType="text/xml; charset=UTF-8"%>
<%@page import="java.lang.reflect.Method" %>
<%
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
String param=request.getParameter("param");
if(request.getParameter("postFlag")!=null){
param=new String(param.getBytes("ISO8859-1"),"UTF-8");
}
String className=request.getParameter("className");
String methodName=request.getParameter("methodName");
String xmlString="";
Object obj=null;
try{
obj=Class.forName(className).newInstance();
Method m=obj.getClass().getMethod(methodName,new Class[]{java.lang.String.class,javax.servlet.http.HttpServletRequest.class});
xmlString=(String)m.invoke(obj,new Object[]{param,request});
}catch(Exception e){
e.printStackTrace();
}
out.print(xmlString);
%>
很显然这个jsp文件主要是接收Request然后通过反射调用后台的指定方法,再返回后台方法返回的结果;
在index.jsp中加入下面的代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!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=UTF-8">
<title>Test</title>
<script type="text/javascript">
function testAjax(){//响应按钮点击方法
var classPath="com.test.servlet.AjaxServlet";
var method="ajaxTest";
var params={"name":"xumian","age":24}
new Ajax(classPath,method,params).getResult("afterAjax");
}
function afterAjax(json){//ajax 响应后的回调方法
alert(json.name+":"+json.grads.java);
for(var i=0;i<json.books.length;i++){
alert(json.books[i]);
}
}
//ajax 对象
var Ajax=function(classPath,method,params){
this.url="tools/getAjax.jsp?param=''&className="+classPath+"&methodName="+method;
this.args="";
this.parseUrl=function(){//构造ajax 的Url
if(params instanceof Object){//json对象格式的参数
var count=0;
for(var item in params){
if(count===0){
this.args="&"+item+"="+params[item];
}else{
this.args=this.args+"&"+item+"="+params[item];
}
count=count+1;
}
}else if(params!==""&¶ms!==undefined){
this.args="&"+params;
}
this.url=this.url+this.args;
return this.url;
};
this.createXMLHttp=function(){//创建XMLHttp对象
var xmlhttp;
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
};
this.getResult=function(){//调用ajax并返回结果
return this.exeAjax("", false);
};
this.getResult=function(callBack_method){//调用ajax并回调callBack_method 方法
return this.exeAjax(callBack_method, false);
};
this.exeAjax=function(callback_method,isJson){
var xmlHttp=this.createXMLHttp();
xmlHttp.open("GET",this.parseUrl(),false);
xmlHttp.send(null);
if(xmlHttp.status=="200"){
if(callback_method === ""||callback_method===undefined){
try{
return eval("("+xmlHttp.responseText+")");//返回json 类型的结果
}catch(e){
return xmlHttp.responseText;//返回字符串形式的结果
}
}
var method="";
try{
method=callback_method+"("+xmlHttp.responseText.trim()+")";
return eval(method);
}catch(e){
method=callback_method+"('"+xmlHttp.responseText.trim()+"')";
return eval(method);
}
}else{
return "error";
}
};
};
</script>
</head>
<body>
<input type="button" value="test ajax" onclick="testAjax()"/>
</body>
</html>
创建一个供ajax调用的类:AjaxServlet.java
package com.test.servlet;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.test.Student;
import com.test.util.JsonData;
public class AjaxServlet{
private static final long serialVersionUID = -6116994561375612882L;
public String ajaxTest(String param,HttpServletRequest request){
String name=request.getParameter("name");
System.out.println("just a test"+name);
Student student=new Student();
student.setName("xum/" ^%$#@@!?'ian");
student.setAge(24);
student.setBooks(new String[]{"java","Oracle","C"});
Map<String, Integer> grads=new HashMap<String, Integer>();
grads.put("java", 99);
grads.put("C", 90);
student.setGrads(grads);
return JsonData.toJsonObj(student);
}
}
对象转json字符串工具类:
package com.test.util;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class JsonData {
@SuppressWarnings("unchecked")
public static String toJsonObj(Object obj) {
StringBuffer sb = new StringBuffer();
if (obj instanceof Object[]) {
sb.append("[");
Object[] values = (Object[]) obj;
for (int i = 0; i < values.length; i++) {
sb.append(toJsonObj(values[i]) + ",");
}
sb.append("]");
} else if (obj instanceof ArrayList) {
ArrayList list = (ArrayList) obj;
sb.append("[");
for (int i = 0; i < list.size(); i++) {
sb.append(toJsonObj(list.get(i)) + ",");
}
sb.append("]");
} else if (obj instanceof Set) {
Set vset=(Set)obj;
sb.append("[");
Iterator it1 = vset.iterator();
while(it1.hasNext()){
sb.append(toJsonObj(it1.next())+",");
}
sb.append("]");
} else if (obj instanceof Map) {
Map map =(HashMap)obj;
Set set =map.keySet();
Iterator it = set.iterator();
sb.append("{");
while(it.hasNext()){
Object keyObj=it.next();
try{
String key=keyObj.toString().replace("/"", "/////"");
sb.append("/""+key+"/":");
sb.append(toJsonObj(map.get(keyObj)));
sb.append(",");
}catch(Exception e){
sb.append("/""+keyObj+"/":");
sb.append(toJsonObj(map.get(keyObj)));
sb.append(",");
}
}
sb.append("}");
} else {
if (obj instanceof String||obj instanceof Integer
|| obj instanceof Double || obj instanceof Float
|| obj instanceof Long || obj instanceof Character
|| obj instanceof Byte || obj instanceof BigDecimal) {
sb.append("/"");
sb.append(obj.toString().replaceAll("/"", "/////""));
sb.append("/"");
} else {
if(obj==null){
return"/"null/"";
}else if("".equals(obj)){
return "/" /"";
}
StringBuffer objSB = new StringBuffer();
StringBuffer objSB2 = new StringBuffer();
String getMethod = "";
Class c = obj.getClass();
try {
objSB.append("{");
Method[] method=c.getMethods();
for(int i=0;i<method.length;i++){
String methodName=method[i].getName();
if(methodName.startsWith("get")
&&method[i].getParameterTypes().length==0
&&!"getClass".equals(methodName)
&&methodName.length()>3){
String field=methodName.substring(3);
field=field.replaceFirst(field.substring(0, 1), field.substring(0, 1).toLowerCase());
try{
Object objValue=c.getMethod(methodName, new Class[]{}).invoke(obj, new Object[]{});
objSB.append("/""+field+"/":");
objSB.append(toJsonObj(objValue));
objSB.append(",");
}catch(Exception nme){
System.out.println("[warn] no method of "+ getMethod + " in "+c.getName());
}
}
}
objSB.append("}");
sb.append(objSB.toString());
} catch (Exception e) {
objSB2.append("/"");
objSB2.append(obj.toString().replaceAll("/"", "/////""));
objSB2.append("/"");
sb.append(objSB2.toString());
}
}
}
return sb.toString().replaceAll(",}", "}").replaceAll(",]", "]");
}
}
测试中用到的实体类:
package com.test;
import java.util.Map;
public class Student {
private String name;
private int age;
private String[] books;
private Map grads;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public Map getGrads() {
return grads;
}
public void setGrads(Map grads) {
this.grads = grads;
}
}
启动项目,在页面上点击testAjax按钮就可以看到从后台返回的结果了;