jarの準備
- なぜこの2つのjarパッケージが使われているかというと、このjarを通してxml設定ファイルを解析する必要があるからです。 
新しいプロジェクト
プロセスソート
- struts設定ファイル
<?xml version="1.0" encoding="UTF-8"?>
<struts>
<package>
 <action name="login" method="login" class="org.zxh.action.LoginAction">
 <result name="success">/index.jsp</result>
 <result name="login">/WEB-INF/login.jsp</result>
 </action>
</package>
</struts>
- この設定ファイルの名前を変更することができ、ここでは、この設定ファイルの役割の簡単な説明は、最初のアクションノードを見つけるこのアクション名はログインである、つまり、この設定ファイルは、このログイン後にフォアグラウンドの要求が解析されるこのアクションのclass属性へのリクエスト、つまり、上記の
org.zxh.action.LoginAction
具体的には、このクラスのlogin(method)メソッドです。このメソッドは、index.jspにリダイレクトされたページで成功した場合、login.jspにリダイレクトされたページでログインした場合、文字列型のメソッドになります。と書かれているので、ここでは、strutsのフレームワークが多くのものをカプセル化することを望んでいるわけではなく、ここでは、読者にstrutsの仕組みの動作をより深く理解してもらうためだけのものです。
書かれたstruts.xmlファイルをプログラムで起動するには?
- コンフィギュレーション・ファイルでフロントとバックのやりとりができるのか?答えはもちろん違います。ここでは、基本的な連絡先のWebフィルタを普及させるために、各インタラクションは、フィルタ(jspは特別なサーブレットです)を必要とするので、相互作用を達成するために、新しいサーブレットを作成する必要があります、このサーブレットでstruts.xmlファイルを読み書きすることにより、操作の次のステップを決定するための情報。では、どのようにフィルタを開始しますか?これは、直接Webプロジェクトのweb.xmlの設定インターセプターがフィルタを実行する、あまり言うことはありません。
新しいフィルタ
- このサーブレットは、strutsのコアフィルタなので、まず、このフィルタを継承する必要があります。
public class FilterDispatcher implements Filter{
@Override
public void destroy() {
 // TODO Auto-generated method stub
 
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
 FilterChain arg2) throws IOException, ServletException {
 // TODO Auto-generated method stub
 
}
@Override
public void init(FilterConfig arg0) throws ServletException {
 // TODO Auto-generated method stub
 
}
}
- 初期化関数のフィルターでいくつかのパラメーターを初期化し、それらのデータの初期化ですね!もちろん、それは設定ファイルの情報を取ることです。設定ファイルは.xmlで、ここではdom4jで.xmlの設定ファイルを読み込むようにしています。 Struts.xmlの設定ファイルは、srcの下にあります。
// xml設定ファイルを取得する
String webRootPath = getClass().getClassLoader()
 .getResource("struts.xml").getPath();
- 読み込みを開始する設定ファイルへのパスを取得した後、ここではマップにカプセル化されたデータの読み込みについて説明します。コンフィギュレーション・ファイルを詳しく見るために、マップにカプセル化された中で
- 実際には、マップの内側にこれらの4つの属性の値であり、これらの4つの値は、インタラクティブマッピングの前面と背面を一度完了することができます。ですから、ここでの作業を容易にするために、javabeanにカプセル化されています。
package org.zxh.util;
import java.util.HashMap;
import java.util.Map;
/**
 * アクションの属性をクラスにカプセル化する
 * 
 *
 */
public class ActionConfig {
	
	//action 他の人にコール名を教える
	private String name;
	//actionプログラムのアクションクラスに対応する
	private String clazzName;
	//actionメソッド
	private String method;
	//結果を返すので、Mapを使用する
	private Map<String, String> resultMap = new HashMap<String, String>();
	
	public ActionConfig(){
		
	}
	
	public ActionConfig(String name , String clazzName , String method , Map<String, String> resultMap){
		this.name=name;
		this.clazzName=clazzName;
		this.method=method;
		this.resultMap=resultMap;
	}
	public String getName() {
		return name;
	}
	public String getClazzName() {
		return clazzName;
	}
	public String getMethod() {
		return method;
	}
	public Map<String, String> getResultMap() {
		return resultMap;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setClazzName(String clazzName) {
		this.clazzName = clazzName;
	}
	public void setMethod(String method) {
		this.method = method;
	}
	public void setResultMap(Map<String, String> resultMap) {
		this.resultMap = resultMap;
	}
	
}
- javabeanでxmlファイルの解析を開始します。
package org.zxh.util;
import java.io.File;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
 * dom4jを使ってxml設定ファイルを解析する
 * 
 * 
 * 
 */
public class ConfigUtil {
	/**
	 * @param fileName
	 * パースされるドキュメント
	 * @param map
	 * 解析されたデータを保存する
	 */
	public static void parseConfigFile(String fileName,
			Map<String, ActionConfig> map) {
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(new File("D:\\zxh\\soft\\apache-tomcat-7.0.70\\apache-tomcat-7.0.70\\webapps\\MyStruts\\WEB-INF\\classes\\struts.xml"));
			Element root = doc.getRootElement();
			List<Element> list = root.selectNodes("package/action");
			for (Element element : list) {
				// ActionConfigオブジェクトにカプセル化され、マップに保存される
				ActionConfig config = new ActionConfig();
				// アクションの値を取得する
				String name = element.attributeValue("name");
				String clazzName = element.attributeValue("class");
				String method = element.attributeValue("method");
				// javabeanに値を渡す
				config.setName(name);
				config.setClazzName(clazzName);
				// 実行メソッドをデフォルトの
				if (method == null || "".equals(method)) {
					method = "execute";
				}
				config.setMethod(method);
				// returnメソッドでアクションを取得するために下に進む
				List<Element> resultList = element.selectNodes("result");
				for (Element resultElement : resultList) {
					String resultName = resultElement.attributeValue("name");
					String urlPath = resultElement.getTextTrim();
					if (resultName == null || "".equals(resultName)) {
						resultName = "success";
					}
					config.getResultMap().put(resultName, urlPath);
				}
				map.put(name, config);
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
- さて、フィルタの話に戻りますが、上の2つのクラスはxmlをパースするためのものです。ですから、フィルタのinitメソッドで、パースされたデータをグローバルマップに入れることができます。
@Override
public void init(FilterConfig arg0) throws ServletException {
 // TODO Auto-generated method stub フィルタの初期化処理
 // xml設定ファイルを取得する
 String webRootPath = getClass().getClassLoader()
 .getResource("struts.xml").getPath();
 // xml設定ファイルを解析してマップに読み込む
 ConfigUtil.parseConfigFile(webRootPath, map);
}
フィルタの実行
- フィルタは、doFilterメソッドの開始時に実際に実行されます。
public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2)
doFilter() メソッドは Servlet インターフェイスの service() メソッドに似ています。クライアントが対象のリソースをリクエストすると、 コンテナは対象のリソースに関連付けられたフィルタの doFilter() メソッドをコールします。ここで、パラメータリクエスト、レスポンスは、Webコンテナまたは最後のFilterのFilterチェーンは、リクエストと対応するオブジェクトに渡されます。現在のFilterチェーンの代わりにオブジェクトのパラメータチェーンは、特定の操作の完了時に、あなたはchain.doFilter(リクエスト、レスポンス)メソッドのFilterChainオブジェクトを呼び出すことができます。特定の操作の完了後に FilterChain オブジェクトの response) メソッドを呼び出すと、Filter チェーン内の次の Filter または処理対象の Servlet プログラムにリクエストを配信したり、レスポンス情報をクライアントに直接返したり、RequestDispatcher の forward() および include() メソッドやHttpServletResponse の sendRedirect() メソッドを使ってリクエストを別のリソースにリダイレクトすることもできます。このメソッドのリクエストとレスポンスのパラメータの型は ServletRequest と ServletResponse です。
- リクエストとレスポンスのフィールドとフィルターチェーンを取得し、文字化けを防ぐためにエンコーディングを設定します。
//httpリクエストの場合、リクエストとレスポンスのHTTPタイプ削減のタイプ
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
//リクエストとレスポンスのエンコード問題を設定する
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
- リクエストアドレスの取得
//リクエストパスを取得する
String url = request.getServletPath();
- このアドレスをフィルタリングするために要求を傍受するかどうかを決定するために要求を通して、この記事のデフォルトは、.actionで終わるすべての要求をフィルタリングします。
//リクエストアドレスのフィルタリング、しない場合.action 
if(!url.endsWith(".action")){
 // .action 
 arg2.doFilter(request, response);
 return ;
}
- xmlファイルのMapに入れたデータのフォーマットを見てください。javabean全体をアクションの名前でMapに入れるという話なので、その名前(リクエストのloginです)に行きます。
//リクエストパスを解析する
int start = url.indexOf("/");
int end = url.lastIndexOf(".");
String path=url.substring(start+1,end);
//対応するActionConfigクラスにパスを合わせる。ここでは、全てのアクション情報を解析している。
ActionConfig config = map.get(path);
//マッチが失敗し、ページが見つかりませんエラーメッセージを返す
if(config==null){
 response.setStatus(response.SC_NOT_FOUND);
 return ;
}
- ActionConfigクラスを取得し、すべての情報のアクションは、このjavabeanクラスに格納されている、次のことが良いです。以下は、リフレクションの知識を使用するだけです。実際のアクションクラスの名前を取得した後、エンティティクラスのアクションに名前を取得する必要があります。
//ActionConfigで完成したクラス名を取得する
String clazzName=config.getClazzName();
//Actionオブジェクトをインスタンス化し、存在しない場合はエラーメッセージが表示される!
Object action = getAction(clazzName);
if(action==null){
 //このアクションは間違っている、設定ファイルでは、対応するアクションクラスを考慮していない
 response.setStatus(response.SC_NOT_FOUND);
 return ;
}
リクエストパラメータが取得され、アクションに割り当てられます。
- アクションメソッドを実行する前に、リクエストのパラメータを取得し、それらを代入する必要があります。
public static void requestToAction(HttpServletRequest request , Object action )
- 入力されたアクション・オブジェクトをクラス分けし、アクション・エンティティのプロパティを取得します。
Class<? extends Object> clazzAction = action.getClass();
//フォアグラウンドから全ての属性をacitonして多くの値を取得し、アクション属性だけが代入の値を反映しなければならない
Field[] fields = action.getClass().getDeclaredFields();
- リクエストから渡された値を繰り返し処理します。
//リクエストのname属性の値を取得する
Enumeration<String> names=request.getParameterNames();
String name=names.nextElement();
boolean flag=false;
//アクション属性を決定する必要がリクエストにない処理を反映する必要はない
for (Field field : fields) {
 if(name.equals(field.getName())){
 flag=true;
 }
}
if(!flag){
 return;
}
String[] value=request.getParameterValues(name);
- リクエストに名前を渡し、アクションに属性を持たせた後、アクションフィールドの属性を取得する必要があります。
Class<Object> fieldType=(Class<Object>) clazzAction.getDeclaredField(name).getType();
- アクションの change name フィールド属性の set メソッドを取得します。
//この属性のsetメソッドをリフレクションで呼び出す
String setName="set"+name.substring(0,1).toUpperCase()+name.substring(1);
Method method=clazzAction.getMethod(setName, new Class[]{fieldType});
- 以下は、タイプ別に取得した値に対して必要な処理です。
private static Object[] transfer(Class<Object> fieldType , String[] value){
 Object[] os = null;
 //fieldType  []このタイプは[] 
 String type=fieldType.getSimpleName().replace("[]", "");
 if("String".equals(type)){
 os=value;
 }else if("int".equals(type)||"Integer".equals(type)){
 os = new Integer[value.length];
 for (int i = 0; i < os.length; i++) {
 os[i] = Integer.parseInt(value[i]);
 }
 }else if("float".equals(type)||"Float".equals(type)){
 os=new Float[value.length];
 for (int i = 0; i < os.length; i++) {
 os[i]=Float.parseFloat(value[i]);
 }
 }else if("double".equals(type)||"Double".equals(type)){
 os=new Double[value.length];
 for (int i = 0; i < os.length; i++) {
 os[i]=Double.parseDouble(value[i]);
 }
 }
 return os;
}
- オブジェクトデータを取得した後、リフレクションによってアクションの対応するプロパティに支払われるのはオブジェクトデータです。
//配列属性
if(fieldType.isArray()){
 method.invoke(action, new Object[]{object});
}else {
 method.invoke(action, new Object[]{object[0]});
}





