Struts随写
原创
©著作权归作者所有:来自51CTO博客作者简单美好的原创作品,请联系作者获取转载授权,否则将追究法律责任
1.Struts的原理或业务流程
漂亮回答面试官struts2的原理
①.工作原理
在Struts2框架中的处理大概分为以下几个步骤
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
②工作流程
1、客户端浏览器发出HTTP请求. 2、根据web.xml配置,该请求被FilterDispatcher接收
3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面
6、返回HTTP响应到客户端浏览器
看到网友的对Struts2的原理总结,我自己也总结以便后续的面试,以下是我的疑问
1、客服端发起一个请求,通过HTTP协议指向Tomcat容器,tomcat拿到请求她干了什么?
2、我们web.xml配置
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我们从web配置文件中可以看到org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,这个Filter这个类有什么用?
这个 /* 是拦截所有的请求,他拦截了请求做了什么处理? <url-pattern>/*</url-pattern>
3.我们struts.xml配置
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="hello">
<result>
/Hello.jsp
</result>
</action>
</package>
</struts>
2.什么地方会出现Action
①.前端提交的form表单
<form action="test/login" method="post">
用户:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登陆"><br>
</form>
所以可以理解为action就是获得数据返回数据的方法。
在SSH框架中拦截器调用中url->web.xml->struts.xml->action->service->biz->dao
②.struts.xml中会配置action拦截url,执行相关操作
其中struts.xml中会配置拦截器action,这里package中继承不同,在其后的result中的type也不同
<action name="RoleAction_*" class="roleAction" method="{1}">
<result name="roleListPage">/roleList.jsp</result>
<result name="addRolePage">/editRole.jsp</result>
<result name="roleListAction" type="redirectAction">
<param name="namespace">/</param>
<param name="actionName">RoleAction_findAllRoles</param>
</result>
<result name="editRolePage">/editRole.jsp</result>
</action>
<action name="Login_*" class="action.LoginAction" method="{1}">
<result type="json" name="success">
<!-- 此处将reslut的值返回给客户端,root的值对应要返回的值的属性result
注意:root为固定写法,否则不会把result的值返回给客户端 -->
<!--<param name="root">username</param>-->
<!--此时返回为null,只有指定值-->
</result>
</action>
<!-- <package name="default" namespace="/" extends="struts-default,json-default"> -->
1.method中{1}
是通配符,和前面的name中*
所匹配,达到简写的目的。
2.result中name为method中的return返回结果,跳转到相应页面。
3.需要在result中使用json时,需继承 json-default.xml,没有的话需要导入jar依赖包。
4.如果type为json,返回数据就为json格式,为action.java中private中含有get方法的所有取值。
{“id”:0,”password”:”123”,”registerTime”:null,”remarks”:null,”username”:”123”}
③action.java
action.java获得前端接受的数据,返回对应结果,或跳转相应页面
action实现方式有4种:
Action的四种实现方式参考
1.普通的POJO类,注意实现execute方法
public class LoginAction {
//私有属性
private String username;
private String password;
//struts2的拦截器机制 getter setter 方法负责解析用户请求参数 并且将请求参数值赋给action对应的属性
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;
}
//普通的execute方法
public String execute() throws Exception {
if("test".equals(getUsername())&&"123".equals(getPassword())){
return "success";
}else{
return "error";
}
}
}
2.实现Action接口
public class LoginAction1 implements Action
//私有属性
private String username;
private String password;
//struts2的拦截器机制 getter setter 方法负责解析用户请求参数 并且将请求参数值赋给action对应的属性
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;
}
//execute方法,和方式一比较“success”变为SUCCESS ERROR变为ERROR
public String execute() throws Exception {
if("test".equals(getUsername())&&"123".equals(getPassword())){
return SUCCESS;
}else{
return
3.继承ActionSupport
public class LoginAction2 extends ActionSupport
//私有属性
private String username;
private String password;
//struts2的拦截器机制 getter setter 方法负责解析用户请求参数 并且将请求参数值赋给action对应的属性
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;
}
//execute方法和方式二比较没变
public String execute() throws Exception {
if("test".equals(getUsername())&&"123".equals(getPassword())){
return SUCCESS;
}else{
return
4.模型驱动
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
//私有的请求参数
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;
}
public User() {
super();
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
public class LoginAction3 implements Action,ModelDriven<User> {
//定义用于封装请求参数和处理结果的Model
private User user=new User();
//execute方法和方式二比较没变
public String execute() throws Exception {
if("test".equals(user.getUsername())&&"123".equals(user.getPassword())){
return SUCCESS;
}else{
return ERROR;
}
}
//重写getModel方法
@Override
public User getModel() {
return
SSH框架中实现的一种属于模型驱动
/**
* 书写BaseAction让其余Action继承
*/
public abstract class BaseAction<T> extends ActionSupport implements
ModelDriven<T>, Preparable {
private static final long serialVersionUID = 1L;
public BaseAction() {
try {
/**
* BaseAction主要干什么?
* 接受前端提交的form input
* input必须和entity中字段名相同
*/
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
Class<T> clazz = (Class<T>) type.getActualTypeArguments()[0];
model = (T) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("来到BaseAction");
}
protected T model;
@Override
public void prepare() throws Exception {
}
@Override
public T getModel() {
return
public class LoginAction extends BaseAction<UserinfoEntity> {