前言
这几天看完了struts视频,现在回来把struts的原理来屡屡,把它转化为能量,以便更好的往下学习。
概述
struts是apache公司的开源子项目,是基于MVC逻辑分层的web层框架实现,应用广泛。struts关注的是控制层,对于view层提供了大量的标签,model层的影响很小。
实现原理
web客户端向服务器(tomcat)发送请求服务,解析http协议。
tomcat进入Comfig文件匹配,匹配成功后进入actionServlet请求dopost(doget),这个时候就会获取到数据。
然后进入RequestProcessor调用process方法,在这个方法里,首先是通过processPath截取URL。
再通过processMapping根据截取的URL取得ActionMapping;然后到了processActionForm,根据ActionMapping的name名称查找ActionForm,如果配置了ActionForm那么就到request或session中查到, 如果request或session中存在已经创建的ActionForm,那么将返回,如果不存在,会根据ActionForm的完成路径采用发射进行创建,再将创建好的ActionForm放到request或session中。
之后进入processPopulate,在这个过程中,首先执行ActionForm中的reset方法进行重置,然后得到表单中所有输入域的name名称,再调用request getParameterValues(),根据name名称得到相应的值,最后将表单中的数据全部放到一个map中,map的key为表单输入域的名称,map的value为表单输入域的值(字符串数组),接下来调用一个第三方组件BeanUtils,将map中的值,根据ActionForm中的类型先转换好,再调用ActionForm中的setter方法设置到ActionForm上。
接下来就到了processActionCreate,根据Action的完成类名称到Map中去查找,如果在就返回Action对象,否则根据Action类的完整名称采用反射去创建,再将创建好的Action放到Map中,所以Struts1的action是单实例,存在线程安全问题。
完成后上一步后,调用processActionPerform,执行用户自定义的action中execute方法,将ActionMapping,ActionForm,request,response传递过去,将ActionForward放回。
然后再进入processForwardConfig,根据返回的ActionForward完成转向,也就是转发或重定向。
最后渲染jsp,显示在客户端中。
栗子
1、引入jar包至/Webroot/WEB-INF/lib下
2、在web.xml文件中配置ActionServlet
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
3、建立相关的login.jsp/success.jsp/error.jsp页面
4、建立LoginAction.java和loginActionForm.java
LoginAction.java
package com.bjpowernode.struts;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
* 登陆action
* 负责取得表单数据,调用业务逻辑,返回转向信息
* @author yang
*
*/
public class LoginAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginActionForm laf = (LoginActionForm)form;
String username = laf.getUsername();
String password = laf.getPassword();
UserManager userManager = new UserManager();
try{
userManager.login(username, password);
request.setAttribute("username",username);
return mapping.findForward("success");
}catch(UserNotFoundException e){
e.printStackTrace();
request.setAttribute("msg","用户不能找到,用户名称=【" + username + "】");
}catch(PasswordErrorException e){
e.printStackTrace();
request.setAttribute("msg","密码错误!");
}
return mapping.findForward("error");
}
}
loginActionForm.java
package com.bjpowernode.struts;
import org.apache.struts.action.ActionForm;
/**
* 登录ActionForm,负责表单收集数据
* 表单的属性必须和ActionForm中的get和Set的属性一致
* @author yang
*
*/
@SuppressWarnings("serial")
public class LoginActionForm extends ActionForm{
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
5、将LoginAction、LoginActionFrom和相关的jsp配置到struts-config.xml文件中
<struts-config>
<form-beans>
<form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/>
</form-beans>
<action-mappings>
<action path="/login"
type="com.bjpowernode.struts.LoginAction"
name="loginForm"
scope="request"
>
<forward name="success" path="/login_success.jsp"/>
<forward name="error" path="/login_error.jsp"/>
</action>
</action-mappings>
</struts-config>
总结
至此,算是把struts1消化了,可以安心往下走了。