Struts2.1.x、Hibernate3.5.X実戦総括


作者:隔壁老王(wallimn.iteye.com)、本人オリジナル、転載を歓迎します.転載してこの情報を残してください.2010-06-25
struts 2を使い始めたばかりです.1.8、Hibernate3.5.3、絶えず問題にぶつかって、問題を解決する.新しいことを学ぶのはやはり人を痛めて楽しくさせます.
いくつかのものを記録して、他の友达に役に立つことを望んでいます.
(一)validateXxxは異なるinputページを返す
多くの人は1つのクラスの複数のメソッドを採用します.複数のメソッドが検証を入力する必要がある場合は、検証に失敗するとそれぞれの異なる入力ページが返され、strutsのデフォルトでは統一されたinputページが返されます.アプリケーションの要件を満たすことは明らかではありません.
解決方法:
ActionにValidationWorkflowAwareインタフェースを実装させ、getInputResultName()メソッドに適切な戻り値を設定します.
comを表示できます.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptorのソースコードはその原理を明らかにします.
注釈の方法を使ってもいいという人もいます.

public class DownloadController extends ActionSupport {

@InputConfig(methodName="inputIndex")
//@InputConfig(resultName="input")
public String index() {
System.out.println("-------index-----------");
return "xx";
}

public void validateIndex() {
addFieldError("hell", ".my hello.");
System.out.println("ok");
}

public string inputIndex() {
return "input";
}
} 

(二)beanutilsを用いる.Populateがrequestのparameterをbeanに移行した場合の日付フォーマット文字列の処理
  beanutils.populateメソッドでは、コミットされたフォームの内容をbeanインスタンスに自動的に組み立てることができ、非常に便利です.
最新バージョンのbeanutilsパッケージは、より強力な自動変換機能を提供しています.一般に、日付タイプを含むbeanについては、日付選択コントロールによって、yyyy-MM-ddの形式を満たすか、空にするかをユーザーの入力を制限できます.ただし、ユーザがアップロードした日付文字列が空白文字列の場合、異常が発生します.
これは、変換器をカスタマイズすることで解決できます.

/**
 * 
 */
package com.wallimn.common.util;

import java.util.Date;

import org.apache.commons.beanutils.converters.DateTimeConverter;

/**
 * <br/>
 *   :wallimn   :2010-6-24   05:36:24<br/>
 *   :V1.0<br/>
 */
public class MyDateConverter extends DateTimeConverter {

	/* (non-Javadoc)
	 * @see org.apache.commons.beanutils.converters.AbstractConverter#getDefaultType()
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected Class getDefaultType() {
        return Date.class;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	protected Object convertToType(Class targetType, Object value)
			throws Exception {
		if(value==null || "".equals(value)){
			return null;
		}
		return super.convertToType(targetType, value);
	}

	public MyDateConverter(){
		super();
	}
	public MyDateConverter(Object defaultValue){
		super(defaultValue);
	}

}

登録方法:

static {
    MyDateConverter d = new MyDateConverter ();
    String[] datePattern = { "yyyy-mm-dd", "yyyy/mm/dd", "yyyy.mm.dd" };
    d.setPatterns(datePattern);
    ConvertUtils.register(d, java.util.Date.class);
  }

これで日付文字列をbeanオブジェクトに取り出すことができ、空欄も異常を起こさない.

public static void populate(HttpServletRequest request, Object obj) {
    Map map = request.getParameterMap();
    try {
      BeanUtils.populate(obj, map);
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
  }

(三)xwork 2.1.6のjarパッケージ、ソースコード、ドキュメントのダウンロードアドレス:
http://release.opensymphony.com/xwork/2.1.6/xwork-assembly-2.1.6-all.zip
命名はとても規範的で、後で新しいバージョンを出して、上の数字を変えることができます.
(四)1 Action複数メソッド(method)に関する問題
現在、いくつかの問題が発生しています.
各メソッドはそれぞれ入力検証を行い、検証に失敗してそれぞれの入力ページに戻る(前述したように、Actionはインタフェースを実現する:ValidationWorkflowAware);
tokenブロッキングは特定の方法のみをブロックする.
以上のいくつかの問題はパラメータ構成によって解決することができ、もちろんActionは関連パラメータのget、setメソッドを提供する.

<?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="com.wallimn.action.sys" namespace="/pages/sys" extends="wallimn">
        <action name="User_*" method="{1}" class="com.wallimn.action.sys.UserAction">
        	<param name="methodName">{1}</param>
        	<param name="inputResultName">{1}_input</param>
        	<!--          、     -->
        	<param name="methodSuccessResultName">{1}_success</param>
        	<param name="methodErrorResultName">{1}_error</param>
        	<param name="methodInputResultName">{1}_input</param>
        	<interceptor-ref name="defaultStack"/>
        	<interceptor-ref name="token">
        		<param name="sys_token"/>
        		<!--     ,                   -->
        		<param name="includeMethods">register</param>
        	</interceptor-ref>
            <result>/pages/sys/login.jsp</result>
            <result name="login_input">/pages/sys/login.jsp</result>
            <result name="login_success">/pages/sys/login_success.jsp</result>
        </action>
        <action name="Sys_*" class="com.wallimn.action.GeneralAction">
            <result>/pages/sys/{1}.jsp</result>
        </action>
    </package>
</struts>

(四)XML結果を返すこともjson結果を返すこともできるstruts結果タイプをカスタマイズする
struts 2はjson結果タイプを持っていて、直接xml結果タイプがなくて、自分で1つ書いて、試験して、効果は悪くありません.xmlタイプの結果は、主にdhtmlXTreeコントロールで使用します.
クラス定義

package com.wallimn.common.util;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.dispatcher.StrutsResultSupport;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.ValueStack;

/**
 *    XML,  json  <br/>
 *   :wallimn   :2010-6-29   05:11:25<br/>
 *   :V1.0<br/>
 */
public class AjaxResult extends StrutsResultSupport {

	/**
	 *   :<br/>
	 *   :2010   05:11:48
	 */
	private static final long serialVersionUID = -1253157812823444791L;

	public AjaxResult(){
		super();
	}
	public AjaxResult(String location){
		super(location);
	}
	private String contentType="text/xml;charset=UTF-8";
	private String xmlHead=null;
	private String charset="UTF-8";
	private String nocache="true";
	/**
	 *      key
	 */
	public final String KEY_CONTENT="ajax.resultstring.by.wallimn";
	/**
	 *       xml    
	 */
	public final String KEY_ADDXMLHEAD="ajax.addxmlhead.by.wallimn";
	/* (non-Javadoc)
	 * @see org.apache.struts2.dispatcher.StrutsResultSupport#doExecute(java.lang.String, com.opensymphony.xwork2.ActionInvocation)
	 */
	@Override
	protected void doExecute(String finalLocation, ActionInvocation invocation)
			throws Exception {
		HttpServletResponse response = (HttpServletResponse) invocation.getInvocationContext().get(HTTP_RESPONSE);
		PrintWriter pw = response.getWriter();
		
		resolveParamsFromStack(invocation.getStack());
		
		response.setContentType(contentType);
		
		response.setCharacterEncoding(charset);

		if(!"false".equals(nocache)){
			response.setHeader("pragma", "no-cache");
			response.setHeader("cache-control", "no-cache");
			response.setHeader("expires", "0");
		}
		
		if(xmlHead!=null && !"".equals(xmlHead)){
			Boolean bAddHead = (Boolean) invocation.getInvocationContext().get(KEY_ADDXMLHEAD);
			if(bAddHead!=Boolean.FALSE){
				pw.println(xmlHead);
			}
		}
		
		String resultString = (String) invocation.getInvocationContext().get(KEY_CONTENT);
		
		pw.println(resultString);
		
		response.getWriter().flush();
	}
	protected void resolveParamsFromStack(ValueStack stack){
		String contentType = stack.findString("contentType");
		if(contentType!=null){
			this.setContentType(contentType);
		}
		String charset = stack.findString("charset");
		if(charset!=null){
			this.setCharset(charset);
		}
		String xmlHead = stack.findString("xmlHead");
		if(xmlHead!=null){
			this.setXmlHead(xmlHead);
		}
		String nocache = stack.findString("nocache");
		if(xmlHead!=null){
			this.setNocache(nocache);
		}
	}
	public void setContentType(String contentType) {
		this.contentType = contentType;
	}
	public String getContentType() {
		return contentType;
	}
	public void setCharset(String charset) {
		this.charset = charset;
	}
	public String getCharset() {
		return charset;
	}
	public void setXmlHead(String xmlHead) {
		this.xmlHead = xmlHead;
	}
	public String getXmlHead() {
		return xmlHead;
	}
	public void setNocache(String nocache) {
		this.nocache = nocache;
	}
	public String getNocache() {
		return nocache;
	}

}

ファイルの作成

    <package name="wpsystem" namespace="/" extends="struts-default">
	    <result-types>
	    	<result-type name="ajaxResult" class="com.wallimn.common.util.AjaxResult"></result-type>
	    </result-types>
        <global-results>
        	<result name="ajax.xml" type="ajaxResult">
        		<param name="contentType">text/xml;charset=UTF-8</param>
        		<param name="xmlHead">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;</param>
			</result>
        	<result name="ajax.json" type="ajaxResult">
        		<param name="contentType">text/plain;charset=UTF-8</param>
			</result>
        </global-results>
    </package>

使い方が簡単

	public String unittreexml() throws Exception{
		String xml = "XML   ";
		ActionContext.getContext().put(KEY_CONTENT,xml);
		return "ajax.xml";
	}
	public String json() throws Exception{
		ActionContext.getContext().put(KEY_CONTENT,"{email:'[email protected]',name:'wallimn'}");
		return "ajax.json";
	}

(五)request、responseを得る方法
直接取得方法:

HttpServletRequest request = ServletActionContext.getRequest ();  
//  :
ActionContext ct= ActionContext.getContext() ; 
HttpServletRequest request=  
(HttpServletRequest)ct.get(ServletActionContext.HTTP_REQUEST);

またはIOCメソッドを使用します.
ステップ1:ActionにサーブレットRequestAwareインタフェースを実装させる
ステップ2:アクションでHttpServertRequestタイプのインスタンス変数を宣言します.
ステップ3:actionでサーブレットRequestAwareインタフェースを実装するsetサーブレットRequestメソッドは、以下に示すように簡単です.
         private HttpServletRequest request;
        public void setServletRequest(HttpServletRequest request) {
            this.request = request;
    }
response処理については同様である.
(六)アップロードファイルが大きすぎる問題:
構成struts.multipart.maxSizeアイテムはあなたが望むサイズです.
デフォルト2,097,152、すなわち2 M(2,09152/1024/1024);
変更可能struts.xmlファイル、定数の追加