面试题一览

第一章-Strtus2概述

1什么是Strtus2

Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开

strtus2执行图

执行原理

  1. 客户端发出一个请求,服务器端的Struts2准备和执行过滤器(StrutsPreparedAndExceuteFilter)接收请求,进行处理。

  2. 由准备和执行过滤器询问ActionMapper来决定这个请求是否需要调用某个Action;

  3. 如果ActionMapper决定需要调用某个Action,准备和执行过滤器把请求的处理交给ActionProxy;

  4. ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类;

  5. ActionProxy创建一个ActionInvocation的实例。

  6. ActionInvocation负责调用Action,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。

  7. Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的jsp页面等进行返回,通常是个JSP页面。

工作流程

  1. Tomcat启动,加载web.xml文件,然后加载核心控制器(StrutsPrepareAndExecuteFilter),加载struts.xml文件

  2. 客户发起HttpServletRequest请求,核心控制器截取请求名称,并从struts,xml中查找,找到后生成Action实例,执行相应方法,获得返回值,根据返回值找到Result中的页面响应给客户端。

2Action配置简单的

先加入jar依赖 。一般不会单独使用,见Spring整合

1
2
3
4
5
6
<!-- struts -->
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.1.8</version>
</dependency>

1配置web.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  <!--设置strtus2的核心过滤器 目的是用于拦截请求strtus2由strtus的规则去处理请求而不是用之前的servlet -->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

2创建普通类

1
2
3
4
5
6
public class loginAction  {
   public String execute1()  {
      System.out.println(this.getClass()+"asddddddddd");
      return "success";
   } 
}

3新建strtus.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
        "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts >
    <package  name="testActionPackage" extends="struts-default">
        <action  name="test1" class="login" method="execute1" >执行的方法
            <result name="success" >show.jsp</result>
        </action>
        <action name="addAction"  class="com.lx.controller.addAction" method="execute1">
            <result name="success" type="redirect">showAction</result>
        </action>
    </package>
</struts>

type的取值

dispatcher :请求转发 redirect ;重定向 redirectAction ;重定向到另一个Action, 会自动拼接动作扩展名。不需要加/

3常见错误

找不到Action可能的原因:

1.—–首先查看你的struts.xml 文件是否在src目录下;

2.—–检查struts.xml文件的语法是否正确:

​ 如果1正确的话那就一定是struts.xml文件的问题

第二章-使用

1Action的创建

1.1方式一普通类

■无侵入式, 无需继承,无需实现接口。 ■但是动作方法必须按规范写。 ●方法必 须用public修饰。 ●方法返回值一 -般为String类型,也可是void类型。 ●方法无参数。 优势:和struts的依赖关系少。 缺点:struts的现成的功能无法使用。 总结:实际开发中使用不多

2.2方式二Action接口

■我们需要实现一个Action接口。 ■并且需要实现execute方法。 ■在 struts.xml中配置action标签时,可以不指定动作方法,默认会执行execute 方法,如果指定了特定方法会走特定方法。 总结: struts的现成功能也无法使用,所以开发中也不常使用。

3.3方式三继承ActionSupport

常用:public class DepartmentActionSupport extends ActionSupport{写Public String 方法}

1
2
3
4
5
6
	<action name="StaffAction"  class="com.lx.control.StaffActionSupport">
		<result name="findOneDepartmentAddSuccess" >addStaff.jsp</result>
		<result name="findOneStaffSuccess" >updateStaff.jsp</result>
		<result name="updateStaffSuccess" type="redirect">StaffAction!findAllStaff</result>
		<result name="deleteStaffSuccess" type="redirect">StaffAction!findAllStaff</result>
	</action>

2提交表单参数

jsp

1
<form class="form-horizontal" action="register!register" method="post">

strtus.xml

1
2
3
4
5
6
7
<package  name="testActionPackage" extends="struts-default">
<action  name="test1" class="login"  >
<result name="success" type="redirect">show.jsp</result>
 result可以写多个 对应不同返回结果
</action>		
  action也可以写多个,对应不同的方法,可以手动加method限定
  但是使用!限定方法更方便

ActionSupport

  • 这里接受参数有两种方法,一种是用基本类型接收,一个input对应一个String 或者其他的,设置get和set方法。

  • 另一中可以,用对象接受,在input加对象的属性名,user.name这种,但是这种移植性不好,

    可以加个 模型驱动接口,然后进行如下几步。

    1
    2
    3
    4
    5
    
     private User user=new User();//这里记住要实例化   
    extends ActionSupport implements ModelDriven<User>   
     public User getModel() {    
     return user;  
    ·}  
    

3访问ServletContext

使用Struts框架提供的类ServletActionContext。可以使用该类的静态方法获取相关对象。

image-20200309151824821

4使用json

1加入依赖,注意版本。

1
2
3
4
5
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-json-plugin</artifactId>
  <version>2.1.8</version>
</dependency>

2Action中

1
2
3
4
5
6
7
8
HashMap<String,Boolean> jsonMap;//注意给其get方法
public String checkName(){
   Boolean valid= usersDao.checkName(user.getUsers_name());
   jsonMap= new HashMap<>();
    jsonMap.put("valid",valid);
    System.out.println("========="+jsonMap.toString());
    return "success";
}

3struts.xml中

注意:extends="json-default"修改继承的拦截器(此拦截器默认继承了struts-default)

​ type为json,jsonMapname为root,jsonMap是aciton中集合名

1
2
3
4
5
6
7
8
9
<!--  Json使用  -->
<package name="ajaxPackage" extends="json-default" namespace="/ajax">
   <action name="register"  class="registerAction" >
       <result name="success" type="json" >
           <!--  成功     xx参数的过滤正则表达式的书写方法xx-->
           <param name="root">jsonMap</param>
       </result>
   </action>
</package>

5拦截器

继承AbstractInterceptor 或者实现Intercerptor

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class loginInterceptor extends AbstractInterceptor{

   @Override
   public String intercept(ActionInvocation invocation) throws Exception {
      //拦截器只拦截action
      System.out.println("拦截器启动");
      String actionName=invocation.getProxy().getActionName();//获得拦截的action名称
      System.out.println("拦截的路径"+actionName);
      if("loginAction".equals(actionName)) {
         //需要放行loginAction 
         return invocation.invoke();//执行invoke方法,执行action中的excute()方法
      }else {
         //获得session中的name
      Object name=ServletActionContext.getRequest().getSession().getAttribute("name");
         if(name!=null) {
            return invocation.invoke();//执行invoke方法,执行action中的excute()方法
         }else {
            return "reLogin";//这种方式返回,只能返回同nameAction的result
         }
      }//if else结束
   }

}

strtus.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
在pakage包内配置拦截器
<interceptors>
<interceptor name="名称" class="位置"></interceptor>
也可以定义拦截器stack,里面可有自定义的interceptory,也可有默认defaultStack
<interceptor-stack name="名称">
<interceptor-ref name="名称"></interceptor-ref>
<interceptor-ref name="defaultStack">stack默认的拦截器</interceptor-ref>
</interceptor-stack>
</interceptors>

设置默认的interceptor-stack
<default-interceptor-ref name="sta"></default-interceptor-ref>

设置全局results
<global-results>
<result name="none" type="redirect" >none.jsp</result>
</global-results>

strtus2常用设置

struts.xml(我们的应用中,能修改 常用) struts. properties(我们的应用中,能修改) web. xml(我们的应用中,能修改。类似简单配置中编码格式的案例。)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <!-- 把它设置为开发模式-->
    <constant name="struts.devMode" value="true" />
    <!-- 设置在class被修改时是否热加载,发布时要设置为false 修改strtus后可以不用重启tomcat -->
    <constant name="struts.convention.classes.reload" value="true"/>
    <!-- 自动动态方法的调用,使用这个设置后可以这样调用:action!method -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <!-- 指定jsp文件所在的目录地址 -->
    <constant name="struts.convention.result.path" value="/WEB-INF/content/" />
    <!-- 使用struts-default默认的转换器,如果是rest的使用:rest-default,rest需要rest的jar插件 -->
    <constant name="struts.convention.default.parent.package" value="struts-default"/>
    <!-- 用于配置包名后缀。默认为action、actions、struts-->
    <constant name="struts.convention.package.locators" value="actions" />
    <!-- 用于配置类名后缀,默认为Action,设置后,Struts2只会去找这种后缀名的类做映射 -->
    <constant name="struts.convention.action.suffix" value="Action"/>
    <!-- 设置即使没有@Action注释,依然创建Action映射。默认值是false。因为Convention-Plugin是约定优于配置的风格,
        可以不通过注解根据预先的定义就能访问相应Action中的方法 -->
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <!-- 自定义jsp文件命名的分隔符 -->
    <constant name="struts.convention.action.name.separator" value="-" />
    <!-- 国际化资源文件名称 -->
    <constant name="struts.custom.i18n.resources" value="i18n" />
    <!-- 是否自动加载国际化资源文件  -->
    <constant name="struts.i18n.reload" value="true" />
    <!-- 浏览器是否缓存静态内容 -->
    <constant name="struts.serve.static.browserCache" value="false" />
     <!-- 上传文件大小限制设置 -->
    <constant name="struts.multipart.maxSize" value="-1" />
    <!-- 主题,将值设置为simple,即不使用UI模板。这将不会生成额外的html标签 -->
    <constant name="struts.ui.theme" value="simple" />
    <!-- 编码格式 相当于设置了HttpRequest,HttpResponse-->
    <constant name="struts.i18n.encoding" value="UTF-8" />

</struts>

常见错误

1jsp类

1表单提交

1
2
感叹号写成了?号
<form class="form-horizontal" action="register!register" method="post">

2strtus.xml类

2.1返回类型

1
2
3
4
<package  name="testActionPackage" extends="struts-default">
<action  name="test1" class="login"  >
  <result name="success" type="redirect">show.jsp</result>
</action>									type类型写错

3ActionSupport类

4其它

4.1json依赖错误

struts2依赖的版本不一致,导致的冲突错误,手动查看targer下的依赖,重启开发软件。

1
2
3
4
5
6
<!-- struts2使用json需要的Jar-->
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-json-plugin</artifactId>
  <version>2.1.8</version>
</dependency>