当前位置: 代码迷 >> Ajax >> Struts2 跟 Ajax 交互
  详细解决方案

Struts2 跟 Ajax 交互

热度:487   发布时间:2012-09-18 16:21:42.0
Struts2 和 Ajax 交互

struts2 的项目的建立我就不多说了,网上很多。这里就说下 struts.xml 里面关于 result 的配置含义,因为 struts2 会通过这个配置来判断你想要做什么样的操作,是重定向、返回数据还是其他什么的,默认配置的结果类型是dispatcher。具体的 result-type 可以 在struts2-core-2.0.11.1.jar 包或 struts2 源代码中的 struts-default.xml 文件中找到,在这个文件中找到标签,所有的result-type都在里面定义了。

?

result-type

class

说明

dispatcher

org.apache.struts2.dispatcher.
ServletDispatcherResult

默认结果类型,用来转向页面,通常处理JSP

chain

com.opensymphony.xwork2.
ActionChainResult

action和另外一个action链接起来

freemarker

org.apache.struts2.views.freemarker.
FreemarkerResult

处理FreeMarker模板

httpheader

org.apache.struts2.dispatcher.
HttpHeaderResult

用来控制特殊的Http行为

redirect

org.apache.struts2.dispatcher.
ServletRedirectResult

重定向到一个URL

redirectAction

org.apache.struts2.dispatcher.
ServletActionRedirectResult

重定向到一个Action

stream

org.apache.struts2.dispatcher.
StreamResult

向浏览器发送InputSream对象,通常用来处理文件下载或者返回数据给 Ajax 调用

velocity

org.apache.struts2.dispatcher.
VelocityResult

处理Velocity模板

xslt

org.apache.struts2.views.xslt.
XSLTResult

处理XML/XLST模板,
XML可以通过XSL模板进行转换

plaintext

org.apache.struts2.dispatcher.
PlainTextResult

显示原始文件内容,例如文件源代码?

?

ajax 调用 action 没什么说的,跟以前 struts1 差不多,直接调用 .action ,直接将参数 post 传递过去,在 action execute 方法或者动态方法中获取参数就可以了;

action 回传数据给 ajax 的时候用到了上面 result-type 里面的 stream 参数配置,将 InputStream 对象返回给浏览器,在ajax 中通过?responseText 来获取返回的值。

有个问题需要说明一下,尽管工程和 jsp 编码都设置成 utf-8,在使用 stream 进行传递的时候仍然会出现乱码问题,这个时候过滤器也是帮不上忙的,需要在生成 InputStream 对象之前的字符串重新编码,否则中文传递到前台就会出乱码。

下面来看看代码:

ajax.jsp

?

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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">
<script type="text/javascript" src="ajax.js"></script>
<title>Insert title here</title>
</head>
<body>
	<form>
		<input type="text" id="nameId"/><br/>
		<span id="nameId2"><span></span></span><br/>
		<span id="msgId"></span><br/>
		<input type="button" onclick="checkUserName()" value="提交"/>
	</form>
</body>
</html>

?

?

ajax.js

?

var xhr ;

// 初始化 xhr 对象
// return value : 1 : IE , 2 , Mozila , 0 : create xhr error ;
function createXHR(){
	// 1,创建xhr 对象 .
	if( window.ActiveXObject ){
		xhr = new ActiveXObject( "Microsoft.XMLHTTP" ) ;
		return 1 ;
	}else if( window.XMLHttpRequest ){
		xhr = new XMLHttpRequest();
		return 2 ;	
	}else{
		return 0 ;
	}	   
}   
  
// ////////// 验证用户名是否存在 ////////////////////

// 将用户填写的用户名发送给服务器端验证
function checkUserName(){
	var ret = createXHR();
	if( ret == 0 ){
		alert( "create xhr error" ) ;
	}else{
		// 在xhr中注册用于处理应答的函数(handleCheck)
		xhr.onreadystatechange = handleCheck ;
		/*
		 * //使用Get方式向服务器发送请求 . 
		 * var url = makeQueryString( "/ajax/reg.jsp" ); 
		 * xhr.open( "get" , url ) ; 
		 * xhr.send( null );
		 */
		  
		// 通过Post 形式向服务器发送数据 .
		var url = "http://localhost:8088/Struts2Demo/ajax_test.action" ;
		xhr.open( "post" , url ) ;   
		xhr.setRequestHeader( "Content-Type" , "application/x-www-form-urlencoded" ) ;
		xhr.send( makeQueryString( null ) ) ;
	}   
}   
  
// 在指定的URL上添加参数
function makeQueryString( url ){
	var name = document.getElementById( "nameId" ).value ;
	var queryString ;
	if( url == null ){
		return "name=" + name ;	
	}else{
		return url + "?name=" + name ;	
	}
}   

function handleCheck(){  
	document.getElementById( "nameId2" ).firstChild.innerHTML="用户名不能为空";
	// 通信过程结束 .
	// readyState : 1: 初始化阶段 2 :连接建立阶段 3 : 通信中阶段 4 : 通信结束
	if( xhr.readyState == 4 ){   
		// status==200,表示服务器运行正常,其他值代表错误
		if( xhr.status == 200 ){
			processResult();
		}else if(document.getElementById( "nameId" ).value==""){
			document.getElementById( "nameId2" ).firstChild.nodeValue="用户名不能为空";
			document.getElementById( "nameId2" ).color="red";	
		}
	}
}
  
function processResult(){
	// 获得应答内容 ,把应答内容显示在网页上
	var span = document.getElementById( "msgId" ) ;
	span.innerHTML = xhr.responseText ;	
}
?

?

AjaxAction.java

?

package com.test.action;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringBufferInputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class AjaxAction extends ActionSupport {

	private InputStream inputStream;

	public InputStream getInputStream() {
		return inputStream;
	}

	public String execute() throws Exception {
		return SUCCESS;
	}

	public String checkUser() throws Exception {
		HttpServletRequest request = null;
		request = ServletActionContext.getRequest();
		// 获取 ajax 传递的 name 参数值
		Object name = request.getParameter("name");
		System.out.println("name=>" + name);
		// 返回 StringBufferInputStream 对象,新的 jdk 里面已经不推荐使用,但推荐使用的 StringReader
		// 并不是 InputStream 接口的实现类,这个比较蛋疼,可以使用下面 test 里面其他的实现类来传递
		inputStream = new StringBufferInputStream(transcoding("struts2 返回 哈哈"));
		return SUCCESS;
	}
	
	public String test() throws Exception {
		// 返回 ByteArrayInputStream 对象至前台,注意跟上面的编码上的区别
		inputStream = new ByteArrayInputStream("乱码测试".getBytes("utf-8"));
		return SUCCESS;
	}
	
	private String transcoding(String str) {
		try {
			return new String(str.getBytes("utf-8"), "iso-8859-1");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}
}
?

?

struts.xml

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<include file="struts-default.xml"></include>
	
	<package name="hello" extends="struts-default">
		<action name="helloworld" class="com.test.action.HelloWorldAction">
			<result>/result.jsp</result>
		</action>
	</package>
	
	<package name="ajax" extends="struts-default">
		<action name="ajax_*" class="com.test.action.AjaxAction" method="{1}">
			<result>/page/ajax/ajax.jsp</result>
			<result type="stream">
				<param name="inputName">inputStream</param>
			</result>
		</action>
	</package>
	
</struts>
?

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>Struts2Demo</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	
	<filter>
        <filter-name>struts-cleanup</filter-name>
        <filter-class>
            com.test.filter.SetCharacterEncodingFilter
        </filter-class>
        <init-param>
        	<param-name>encoding</param-name>
        	<param-value>utf-8</param-value>
        </init-param>
    </filter>  
    <filter-mapping>
        <filter-name>struts-cleanup</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
</web-app>
?

上面配了一个自定义的过滤器,主要处理页面提交的中文编码问题的,本例中可以不用,struts2 当中也是有自带的中文过滤器的,这个自定义的过滤器也顺便贴出来了

SetCharacterEncodingFilter.java

package com.lizanhong.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class SetCharacterEncodingFilter implements Filter {

    protected String encoding = null;

    protected FilterConfig filterConfig = null;

    protected boolean ignore = true;

    public void destroy() {

        this.encoding = null;
        this.filterConfig = null;

    }

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
    throws IOException, ServletException {

        if (ignore || (request.getCharacterEncoding() == null)) {
            String encoding = selectEncoding(request);
            if (encoding != null)
                request.setCharacterEncoding(encoding);
        }

        chain.doFilter(request, response);

    }

    public void init(FilterConfig filterConfig) throws ServletException {

    this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");
        String value = filterConfig.getInitParameter("ignore");
        if (value == null)
            this.ignore = true;
        else if (value.equalsIgnoreCase("true"))
            this.ignore = true;
        else if (value.equalsIgnoreCase("yes"))
            this.ignore = true;
        else
            this.ignore = false;

    }

    protected String selectEncoding(ServletRequest request) {
        return (this.encoding);
    }
}

?

里面的代码尽量省略,应该可以看到最原始的交互过程了。

1 楼 greatwqs 2011-12-06  
  相关解决方案