• 创建一个Web 项目

• 在 WEB-INF/lib 下导入struts 1 的 jar 包

• 配置 web.xml

jsp传list给action从源码看struts框架中DispatchAction 实现 GraphQL

• 如果利用标签,要对标签进行相应的导入和配置

○ struts 标签要导入国际化资源文件

○ jstl 标签要导入两个 jar 包

• 配置主配文件 struts-config.xml [ 全体项目的过程思路 ]

○ 只有一个 <action> 标签,标签中增加了一个 parameter=\"大众command\"大众 属性

§ command -- 规定要求中参数值为方法名的参数名

项目流程 -- 显示信息

• 支配 - 启动 Tomcat:

○ myeclipse 项目文件支配之后存在于 Tomcat/webapps 下

• 进入首页:

------------------------- index.jsp

<a href=\"大众user/usermaint.do\"大众 title=\"大众请点击访问用户管理系统\"大众>用户管理系统</a>

• 发出要求:http://127.0.0.1:8080/struts_training_usermgr/user/usermaint.do:

○ 在 struts-config.xml 中找到对应的 <action>

<form-beans>

<form-bean name=\"大众userForm\"大众 type=\"大众com.bjsxt.drp.web.usermgr.forms.UserActionForm\"大众></form -bean>

</form-beans>

<action path=\"大众/user/usermaint\"大众 type=\"大众com.bjsxt.drp.web.usermgr.actions.UserAction\"大众 name=\"大众userForm\"大众

scope=\"大众request\公众 parameter=\"大众command\公众

>

<forward name=\"大众find_success\公众 path=\"大众/user/user_modify.jsp\"大众/>

<forward name=\"大众list_success\"大众 path=\公众/user/user_list.jsp\"大众/>

</action>

○ 看request 内置工具中是否有表单Bean 工具,没有就进行工具创建,有就利用已有的表单Bean 进行存放网络

○ 由于要求从超链接直接发出,不带参数 -- 虽然创建了 ActionForm,但创建出的 ActionForm 未网络到表单中的数据,保持原值

• 通过 type 创建业务层前端掌握器 Action 并实行父类的 execute() 方法:

------------------------- UserAction.java

------------------------- DispatchAction.java

public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request,HttpServletResponse response) throws Exception {String parameter = mapping.getParameter(); // 从要求对应的配置信息中拿parameter 对应的存放方法名参数值的参数名- command String name = getMethodName(mapping, form, request, response, parameter);// return request.getParameter(parameter); // 返回要求中参数名为 command 的参数值-- 即用户要求的方法名// command 后不许可输入 execute和 performif (\"大众execute\"大众.equals(name) || \"大众perform\"大众.equals(name)){String message = messages.getMessage(\"大众dispatch.recursive\"大众, mapping.getPath()); throw new ServletException(message); }return dispatchMethod(mapping, form, request, response, name); // name 为方法名}

------------------------- dispatchMethod(mapping, form, request, response, name)

protected ActionForward dispatchMethod( ActionMapping mapping, ActionForm form, HttpServletRequest request,HttpServletResponse response, String name) throws Exception { Class clazz= this.getClass(); // 取得当前工具的反射工具Class[] types = { name, ActionMapping.class, ActionForm.class, HttpServletRequest.class, HttpServletResponse.class }// 用户没有输入方法名,就调用Action 中的unspecified() 方法if (name == null) { return this.unspecified(mapping, form, request, response); } // this 是Action// 如果用户输入了方法名,通过方法反射,通过方法名调用对应的方法Method method = null; // 创 建 一 个 封 装 方 法 的 Method 对 象 method = getMethod(name);

ActionForward forward = null;

Object args[] = {mapping, form, request, response}; // 将execute() 方法的参数署名存放在一个Object 类型的数组工具中forward = (ActionForward) method.invoke(this, args); // 创建一个封装了调用方法的ActionForward 工具

return (forward);

}

------------------------- getMethod(name)

protected Method getMethod(String name) throws NoSuchMethodException { synchronized(methods) {Method method = (Method) methods.get(name); if (method == null) {method = clazz.getMethod(name, types); // 将用户放在name 中的方法封装到 method 工具中methods.put(name, method); }return (method); }

}

• 此时用户要求中不带有方法字符串,故实行 Action 中的 unspecified() 方法:

------------------------- UserAction.java

protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request,HttpServletResponse response) throws Exception {// 将业务工具和持久工具都准备好后调用业务工具的 findAllUserList() 方法List userList = UserManager.getInstance().findAllUserList();}

• 通过单例 + 同步进入到业务层

• 业务层 findAllUserList() 方法中调用持久层的对应方法

• 持久层中得到的结果 list 凑集经由业务层传回业务层前端掌握器 Action 后,被设入 request 内置工具中,属性名为 userlist:

------------------------- UserAction.java

protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request,HttpServletResponse response) throws Exception { request.setAttribute(\公众userlist\"大众, userList);return mapping.findForward(\公众list_success\"大众);}

○ 将 list 设入 request 内置工具中之后,Action 返回给 struts 一个封装了转向路径的 ActionForward 工具

• struts 解析 ActionForward 工具后转向相应的 jsp 页面 -- user_list.jsp:

<input name=\"大众btnAdd\"大众 type=\"大众button\公众 class=\公众button1\公众 id=\"大众btnAdd\"大众 value=\公众添加\公众 onClick=\公众addUser()\"大众>

<input name=\公众btnDelete\"大众 class=\公众button1\公众 type=\"大众button\公众 id=\公众btnDelete\"大众 value=\公众删除\"大众 onClick=\"大众deleteUser()\"大众>

<input name=\"大众btnModify\公众 class=\"大众button1\"大众 type=\"大众button\公众 id=\"大众btnModify\公众 value=\公众修正\"大众 onClick=\"大众modifyUser()\"大众>

项目流程 -- 添加

• button 按钮 -- 调用 javascript 的 addUser() 方法 -- 调用出一个添加页面: function addUser() { window.self.location = \公众user_input.jsp\公众; }

○ 在浏览器的地址栏上发出一个要求,访问 user_input.jsp -- 相对路径,默认路径在第一次访问 servlet 的路径

§ 第一次访问 servlet 要求的路径便是 servlet 进行转向的默认路径 -- 作为页面的相对路径

§ 此时通过 javascript 访问 user_input.jsp 是掌握浏览看重新发了一次要求

• user_input.jsp 页面的表单 button 添加按钮 -- 调用 javascript 方法对用户输入进行验证,验证完将要求提交到 add.do:

with (document.getElementById(\公众userForm\"大众)) { method = \公众post\公众; action = \"大众usermaint.do?command=add\"大众; submit(); }

<form name=\"大众userForm\公众 target=\"大众_self\公众 id=\"大众userForm\"大众> …. </form>

○ 此页面中对表单的定义没有 action 属性,action 功能在 javascript 中定义

○ 此处提交的 action=\"大众usermaint.do\"大众,实际在 struts-config.xml 文件中的 path=\"大众/user/usermaint\"大众

• 要求字符串:http://127.0.0.1:8080/struts_training_usermgr/user/usermaint.do?command=add:

<form-beans><form-bean name=\公众userForm\"大众 type=\公众com.bjsxt.drp.web.usermgr.forms.UserActionForm\"大众></form-bean></form-beans><action path=\"大众/user/usermaint\公众 type=\"大众com.bjsxt.drp.web.usermgr.actions.UserAction\公众 name=\"大众userForm\"大众scope=\"大众request\"大众• parameter=\"大众command\公众><forward name=\"大众find_success\公众 path=\"大众/user/user_modify.jsp\公众/><forward name=\"大众list_success\"大众 path=\"大众/user/user_list.jsp\公众/></action>

• 由于是新的一次要求,会重新创建表单Bean,并自动网络数据到表单Bean:

○ 表单Bean 中的属性都是字符串类型

○ 表单Bean 中存在的属性但表单中没有的参数不进行网络

• 通过 type 创建业务层前端掌握器 Action 并实行父类的 execute() 方法:

------------------------- UserAction.java

------------------------- DispatchAction.java

• 此时用户要求中指定方法字符串为 \"大众add\"大众,故实行 Action 中的 add() 方法:

------------------------- UserAction.java

public ActionForward add( ActionMapping mapping, ActionForm form, HttpServletRequest request,

HttpServletResponse response) throws Exception {

//调用业务逻辑操作UserManager.getInstance().addUser(user); return mapping.findForward(\"大众success\公众);

}

• 拿到业务工具的地址,并调用业务层 addUser() 方法,将封装了表单中数据的 user 传给业务层 [ 单例 + 同步:同一时候只能有一个线程进入 ]:

• 业务层调用持久层 addUser() 方法:

• 持久层业务层均实行完后,Action 返回给 struts 一个封装了转向路径的 ActionForward 工具:

<global-forwards><forward name=\"大众success\公众 path=\"大众/user/usermaint.do\"大众 redirect=\"大众true\"大众/></global-forwards>

○ 此 ActionForward 工具中封装的转向办法为客户端跳转

○ 封装的转向路径不是跳转向一个详细的 jsp 页面,而是要求 struts 处理组件

• struts 解析 ActionForward 工具后,再次处理显示用户信息的要求