struts 的 MVC ,自己堆栈跟踪(可以跟着做一遍)
自己做了一个简单的测试Struts2 的MVC流程,并且连接了数据库。需要的包为四个包 commons-logging,ognl,struts2-core,xwork这四个包
当需要连接MySQL数据库的时候需要加包MySQL-connector-java
我们的文件结构为
我们的包加在WEB-INF的lib目录下。web.xml配置在WEB-INF中,在src文件夹里我们有struts.xml配置文件和action实现类
我们的LoginAciton为
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.DateFormat;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport
{
//下面是Action内用于封装用户请求参数的两个属性
private String user;
private String password;
private String name;
//user属性对应的getter方法
public String getuser()
{
return user;
}
//user属性对应的setter方法
public void setuser(String user)
{
this.user = user;
}
//password属性对应的getter方法
public String getPassword()
{
return password;
}
//password属性对应的setter方法
public void setPassword(String password)
{
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//处理用户请求的execute方法
public String execute() throws Exception
{
String ret = ERROR;
Connection conn = null;
try {
String URL = "jdbc:mysql://localhost/struts_tutorial";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(URL, "root", "yuanchao");
String sql = "SELECT name FROM login WHERE";
sql+=" user = ? AND password = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, user);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
name = rs.getString(1);
ret = SUCCESS;
}
} catch (Exception e) {
ret = ERROR;
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
return ret;
}
}
我们在struts.xml中配置相应动作的action
<struts>
<!-- Struts 2的Action必须放在指定的包空间下定义 -->
<package name="strutsqs" extends="struts-default">
<!-- 定义login的Action,该Action的实现类为lee.Action类 -->
<action name="Login" class="LoginAction">
<!-- 定义处理结果和资源之间映射关系。 -->
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
</package>
</struts>
我们在web.xml中配置filter
<filter>
<!-- 定义核心Filter的名称 -->
<filter-name>struts2</filter-name>
<!--定义核心Filter的实现类 -->
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<!--核心Filter的名称 -->
<filter-name>struts2</filter-name>
<!--使用该核心Filter来接受所有的Web请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
在上述的当用户请求参数的同MySQL数据库中的参数相对应返回成功,否则失败
当然我们可以采用
String user = (String)ActionContext.getContext().getSession().get("user");来获得用户名的属性
疑问一:getUsername()就可以获得我们表单里的用户名
堆栈跟踪执行过程
LoginAction.execute()
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
DefaultActionInvocation.invokeAction(Object, ActionConfig) line: 404
DefaultActionInvocation.invokeActionOnly() line: 267
DefaultActionInvocation.invoke() line: 229
DefaultWorkflowInterceptor.doIntercept(ActionInvocation) line: 221
DefaultWorkflowInterceptor(MethodFilterInterceptor).intercept(ActionInvocation) line: 86
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
AnnotationValidationInterceptor(ValidationInterceptor).doIntercept(ActionInvocation) line: 150
AnnotationValidationInterceptor.doIntercept(ActionInvocation) line: 48
AnnotationValidationInterceptor(MethodFilterInterceptor).intercept(ActionInvocation) line: 86
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
StrutsConversionErrorInterceptor(ConversionErrorInterceptor).intercept(ActionInvocation) line: 123
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ParametersInterceptor.doIntercept(ActionInvocation) line: 167
ParametersInterceptor(MethodFilterInterceptor).intercept(ActionInvocation) line: 86
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
StaticParametersInterceptor.intercept(ActionInvocation) line: 105
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
CheckboxInterceptor.intercept(ActionInvocation) line: 83
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
FileUploadInterceptor.intercept(ActionInvocation) line: 207
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ModelDrivenInterceptor.intercept(ActionInvocation) line: 74
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ScopedModelDrivenInterceptor.intercept(ActionInvocation) line: 127
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ProfilingActivationInterceptor.intercept(ActionInvocation) line: 107
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ChainingInterceptor.intercept(ActionInvocation) line: 115
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
I18nInterceptor.intercept(ActionInvocation) line: 143
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
PrepareInterceptor.doIntercept(ActionInvocation) line: 121
PrepareInterceptor(MethodFilterInterceptor).intercept(ActionInvocation) line: 86
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ServletConfigInterceptor.intercept(ActionInvocation) line: 170
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
AliasInterceptor.intercept(ActionInvocation) line: 123
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
ExceptionMappingInterceptor.intercept(ActionInvocation) line: 176
DefaultActionInvocation$2.doProfiling() line: 224
DefaultActionInvocation$2.doProfiling() line: 223
UtilTimerStack.profile(String, ProfilingBlock<T>) line: 455
DefaultActionInvocation.invoke() line: 221
StrutsActionProxy.execute() line: 50
Dispatcher.serviceAction(HttpServletRequest, HttpServletResponse, ServletContext, ActionMapping) line: 504
FilterDispatcher.doFilter(ServletRequest, ServletResponse, FilterChain) line: 423
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 244
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210
StandardWrapperValve.invoke(Request, Response) line: 272
StandardContextValve.invoke(Request, Response) line: 123
NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 506
StandardHostValve.invoke(Request, Response) line: 169
ErrorReportValve.invoke(Request, Response) line: 105
AccessLogValve.invoke(Request, Response) line: 957
StandardEngineValve.invoke(Request, Response) line: 118
CoyoteAdapter.service(Request, Response) line: 438
返回到登录成功跳转页面 看看上面的执行过程的堆栈 醉了 好在有许多函数是重复调用的 我先挑出来
关于下几篇文章
1 分析上述堆栈
2 分析ActionContext
3 分析ActionContext对应的ThreadLocal
4 查找上述的值传递过程