Struts2的学习知识点

 框架:封装通用功能,软件开发的半成品,提高开发效率
        1.接受客户端参数
2.中文字符的编码处理
提供更好的解决方案,提高开发效率
================================================================================
MVC
  *Model  View   Controller
   模型   视图     控制器
  *软件开发过程中,会将代码分成三个部分:
     M   业务模型   业务逻辑,业务内部数据逻辑   Service+DAO  (javabean)
V   视图       展示数据,展示页面            JSP
C   控制器     调度M和V,流程的控制          Servlet
                                               1.接受客户端请求参数
2.调用Model中的Service
3.转发View的JSP
  *好处:
      1.适合多人协同开发
 2.层次清晰,耦合度极低,利于维护
================================================================================
Servlet弊端:
   1.接受客户端请求参数代码冗余
   2.跳转时,将跳转路径写死在代码中,极其不利于维护
================================================================================
struts2
   *apache  基于xwork 开源web框架
   *是一个典型的MVC框架.
   *提供了更好的MVC解决方案:提供了更好的控制器--Action,替换Servlet.
   *第一个struts2程序:helloworld~~
      *编码流程:
    1.导入struts的jar包:struts2核心jar和第三方依赖jar
2.在web.xml中配置struts2核心控制器:
    StrutsPrepareAndExecuteFilter
 (struts2核心jar中org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter)
   *过滤器
*过滤到所有请求
*使得所有请求都进入Struts2的流程控制中
3.引入struts2提供的struts.xml配置文件
   *容纳配置信息:Action配置信息,.......
*位置:
  struts-2.3.16-all\struts-2.3.16\apps\struts2-blank\WEB-INF\classes
4.定义Action类
   public class MyAction implements Action{
public String execute(){
System.out.println("Hello world~~~");
return null;
}
}
5.配置Action类,在struts.xml中
   <package name="pa22"  extends="struts-default">
<!-- 配置Action 
name:等效于servlet的url-pattern
-->
<action name="myaction" class="com.strut_day1.action.MyAction">
</action>
</package>
   6.访问Action
    http://localhost:8989/struts2_day1/myaction
 
   *补充:
  *页面转发
     1.execute返回一个字符串,决定跳转路径
    public String execute(){
System.out.println("Hello world~~~");

return "myret";//决定跳转路径
}
 2.在当前Action的配置中添加一个<result
    <action name="myaction" class="com.strut_day1.action.MyAction">
 <result name="myret">/index.jsp</result>
</action>
 *注意:execute的返回值要和<result 标签的name属性值一致,即可实现跳转
  *Action接收客户端参数:
      1.Servlet中的接收机制:
       *ServletActionContext --工具类---获取当前请求对象 和 响应对象
       HttpServletRequest req=ServletActionContext.getRequest();
String name=req.getParameter("name");
System.out.println("name1:"+name);
  2.struts2提供的接受客户端参数的机制:
       客户端发送参数:
*<form>
<input type="text" name="username"/>
<input type="text" name="password"/>
<input type="submit" value="submit"/>
</form>
*<a href="/应用名/xx?username=zhj&password=123">goto~~</a>
                    Action类中接受参数
*在Action中接收名为username的客户端参数只需要
在Action类中定义一个同名的成员变量即可
*数据处理机制
   1.Servlet中的数据处理机制:
    request.setAttribute("name","zhj");
request.getAttribute("name");
session.setAttribute("name","zhj");
session.getAttribute("name");
servletContext.setAttribute("name","zhj");
servletContext.getAttribute("name");
2.struts2提供的数据处理机制
   NAN
 
  1.Action的运行机制
   和Servlet不同,Action不是单例运行
   而是,为每一个请求创建一个实例
   使得请求之间不存在临界数据的安全问题.
   所以,Action是线程安全的.
*2.package
   1.将配置信息模块化的管理,便于对配置信息的查找,修改.
   2.package标签中的namespace,为当前包中的所有Action都加上了统一的访问前缀,如:
        <package name="teacher" extends="struts-default" namespace="/tea">
<action name="hh" class="com.xxx.AAAction">
<result name="ok">/index.jsp</result>
</action>
<action name="hh1" class="com.xxx.AAAction">
<result name="ok">/index.jsp</result>
</action>
<action name="hh2" class="com.xxx.AAAction">
<result name="ok">/index.jsp</result>
</action>
</package>
在加入namespace之前:
    http://localhost:8989/应用名/hh
http://localhost:8989/应用名/hh1
http://localhost:8989/应用名/hh2
   在加入namespace="/tea"之后:
    http://localhost:8989/应用名/tea/hh
http://localhost:8989/应用名/tea/hh1
http://localhost:8989/应用名/tea/hh2
3.进而真正实现了对于配置信息的模块化管理,不同模块之间零干扰.
4.实战:
  *不同模块的配置信息放到不同的package中
  *且不同的package指定不同的namespace
  -->便于多人协同开发
*注意:namespace="/xxx"   务必要以/开始
*3.Action中收集客户端参数:----代码处于StudentAction1.java中
    *收集零散数据
    <input type="text" name="username"/>
private String username;
set/get
    *将零散数据存入对象中
    entity:
  class Admin{
 private String username;
 private String password;
 set/get
  }
    1.class MyAction implements Action{
      Admin ad;
  set/get
  public String execute(){
  
  }
  }
         2.<form>
      <input type="text" name="ad.username"/>
  <input type="text" name="ad.password"/>
  </form>
*将客户端参数收集到数组或集合中
    1.class MyAction implements Action{
      String[] xq;
  public String execute(){
  
  }
  }
2.<form>
      <input type="checkbox" name="xq" value="football"/>足球
  <input type="checkbox" name="xq" value="basketball"/>篮球
  <input type="checkbox" name="xq" value="volleyball"/>排球 
  </form>
3.如果,选中了足球和排球,则Action中名为xq的数组或集合成员变量中,
  就会,有[football,volleyball]
     *将客户端参数收集到泛型为对象的集合中,或数组中
   1.class MyAction implements Action{
      List<Admin> ads;
  set/get;
  public String execute(){
  
  }
  }
2.<form>
      <input type="text" name="ads[0].username"/>
  <input type="text" name="ads[0].password"/>
  <input type="text" name="ads[1].username"/>
  <input type="text" name="ads[1].password"/>
  </form>
*4.跳转方式 ---代码处于StudentAction2中
   *Action-->JSP
      1.forward
         <result name="ok" type="dispatcher">/abc.jsp</result>
*注意dispatcher是result中默认的跳转类型
*Action和JSP处于同一个请求,地址栏不发生改变
      2.重定向
<action name="stu2" class="com.struts_day2.action.StudentAction2">
   <result name="ok" type="redirect">/abc.jsp</result>
<!--重定向到location所指定的jsp中,并携带之后的param中所指定的客户端参数-->
    <result name="ok" type="redirect">
    <param name="location">/index.jsp</param>
    <param name="name">zhj</param>
<param name="age">18</param>           
    </result>
    </action>
    *Action和JSP处于不同的两个请求中,地址栏发生改变
      *注意:
    forward中传递数据:作用域
redirect中传递数据:作用域
                    客户端参数
 
 
   *Action-->Action
      1.forward
    <result name="ok" type="chain">Action名</result>
*通过chain跳转链接的多个Action处于同一个请求中,地址栏不会发生改变
 2.重定向
    <result name="ok" type="redirectAction">Action名</result>
<!--重定向到Action:stu1 ,并传递客户端参数-->
<result name="ok4" type="redirectAction">
    <param name="actionName">stu1</param>
    <param name="username">class22</param>
    </result>
   
================================================================================
respons.sendRedirect("/应用名/view/a.jsp");
respons.sendRedirect("/应用名/view/a.jsp?name=zhj&age=18");
复习:
*Action---->JSP
     1.请求转发
   <result name="ok" type="dispatcher">/view/show.jsp</result>
2.重定向
        <result name="ok" type="redirect">/view/show.jsp</result>
<result name="ok" type="redirect">
   <param name="location">/view/show.jsp</param>
<param name="name">zhj</param>
<param name="age">18</param>
</result>
*Action---->Action
     1.请求转发
   前提是同包中有:
  <action name="stu1" class="com.struts_day2.action.StudentAction1"></action>
  
   <result name="ok" type="chain">
<param name="actionName">stu1</param>
</result>
2.重定向
        <result name="ok" type="redirectAction">
   <param name="actionName">stu1</param>
<param name="name_22">class22</param>
<param name="age_22">22</param>
</result>
   ;
*跨包跳转
   <package name="pa" extends="struts-default" namespace="/admin">
       <action name="login" class="com.xxx.XXAction">
     <!--跳转到pb包中的query Action-->
     <result name="ok" type="redirectAction">
 <param name="actionName">query</param>
 <param name="namespace">/emp</param>
 </result>
  </action>
   </package>
   <package name="pb" extends="struts-default" namespace="/emp">
       <action name="query"  class="com.xxx.YYYAction">
 <result name="ok">/index.jsp</result>
  </action>
   </package>
   
   
   
   
   
   
   
   
   
   
=========================================================================
补充:
   关联源码:
      *打包部署包---xxxx.zip
 *ctrl+click
 *attch source  选中xxx.zip的路径
 
   *Action要有空参构造
   *默认namespace--->""
       <package name="pa" extends="struts-default">
  
  </package>
  <package name="pa" extends="struts-default" namespace="/">
  
  </package>
   *namespace要加/开始
   *全局跳转:核心作用:将一个package中的重复的result(跳转)抽出出来,避免配置的冗余
     <action name="act1" class="com.xxx.ActionA">
    <result name="ok">/index1.jsp</result>
.....
<result name="loginerror">/login.jsp</result>
</action>
<action name="act2" class="com.xxx.ActionB">
    <result name="ok">/index2.jsp</result>
.....
<result name="loginerror">/login.jsp</result>
</action>
<action name="act3" class="com.xxx.ActionC">
    <result name="ok">/index3.jsp</result>
.....
<result name="loginerror">/login.jsp</result>
</action>
***核心作用:将一个package中的重复的result(跳转)抽出出来,避免配置的冗余,如:
<global-results>
<result name="loginerror">/abc.jsp</result>
</global-results> 
   <action name="act3" class="com.xxx.ActionC">
<result name="ok">/index3.jsp</result>
<result name="loginerror">/login.jsp</result>
</action>
*注意:1.全局跳转只在当前包生效
      2.局部跳转优先,全局跳转次之
 
 
 
*跨包跳转
   <package name="pa" extends="struts-default" namespace="/admin">
       <action name="login" class="com.xxx.XXAction">
     <!--跳转到pb包中的query Action-->
     <result name="ok" type="redirectAction">
 <param name="actionName">query</param>
 <param name="namespace">/emp</param>
 </result>
  </action>
   </package>
   <package name="pb" extends="struts-default" namespace="/emp">
       <action name="query"  class="com.xxx.YYYAction">
 <result name="ok">/index.jsp</result>
  </action>
   </package>
*DMI ---Dynamic Method Invoke吧
*在Action中定义多个可执行的,用来处理请求的方法
1.在Action类中定义:
  public String login(){
System.out.println("login");
return null;
  }
  public String regist(){
System.out.println("regist");
return null;
  }
2.在Action的配置标签中添加method属性:
<!-- http://localhost:8989/应用名/stu/login 
http://localhost:8989/应用名/stu/reg
-->
<action name="login" class="com.day3.action.AdminAction" method="login">
</action>

<action name="reg" class="com.day3.action.AdminAction" method="regist">
</action>
3.实现了在Action中定义多个可用于处理请求的方法.减少Action类的定义个数
4.实战:
一个Action类中定义一个逻辑单元的所有处理方法
*动态调用方法
   admin_*:可以匹配到任何以admin_开始的字符串.
{1}:action配置标签中的name中的第一个*所匹配到得字符串
<action name="admin_*"  class="com.day3.action.AdminAction" method="{1}">
</action>
http://localhost:8989/应用名/前缀/admin_login ----> com.day3.action.AdminAction类中的login方法
http://localhost:8989/应用名/前缀/admin_regist----> com.day3.action.AdminAction类中的regist方法

注意:非重点:
   http://lcoalhost:8989/应用名/前缀/admin_login_abc
   <action name="admin_*_*" class="com.day3.action.AdminAction" method="{1}">
<result name="ok">/{2}.jsp</result>
</action>

**struts2的数据处理机制
    Servlet:
作用域:存储数据
el:获取数据
 jstl:展示数据
 
    Struts2:
          值栈:存储数据
 OGNL:获取数据
   struts2标签:展示数据
   
*OGNL
    1.是一个独立的组件,并不是struts2独有的
2.OGNL---对象图导航语言
   *取值范围:
*root
  1.entity---->属性名
  2.集合List/数组  ---->[0]/[1]
  3.Map  --->key名

*context
  1.Map
*取值方式:
            *root
 1.可以获取到和root关联的任何属性(直接属性,间接属性)
 2.获取到属性后,可以调用属性的类型中定义的任何公开方法
              *通过OGNL从root中取值
      1.直接通过属性名获取属性
  2.导航到任意属性后可以调用方法 
 *A 
   |-name
|-age
|-B b
  B
   |-city
 以A为root
 OGNL:"name"--->获取了name
     :"age"----获取了age
 :"b.city"--->获取了A中的B的属性city
*context
  *从context中取值时,OGNL的定义要以#开始,其余和从root中取值一样
  
   *总结:
  从root取值:
     Ognl的写法:
    Ognl.getValue("属性名",root);//root:entity,list,数组,Map
  往root中赋值:
        Ognl.setValue("属性名",root,值);
  从context中取值
     Ognl的写法
    Ognl.getValue("#属性名",context,root);//context:map
  往context中赋值
        Ognl.setValue("#属性名",context,root,值);


值栈  ValueStack
   本质:一个ValueStack对象
   作用:struts2会为每一个请求创建一个ValueStack对象,用来存储请求处理过程中的数据
===========================================================================================
ValueStack的内部存储结构
    root  ---->栈
 *存储当前请求所访问的Action类的实例对象
 |-EmpAction2
    |-Employee 
 




context  --->Map

key              Value
 "request"            Map ------>等效于requst作用域底层的Map,可以用来操作request作用域
 "session"            Map ------>等效于session作用域底层的Map,可以用来操作session作用域
 "application"        Map ------>等效于application作用域底层的Map,可以用来操作application作用域
      "parameters"         Map ------>存储了客户端请求参数,可以用来读取客户端请求参数(非重点)
 
   "name":"zhj"
   "#request.name"
   
==========================================================================================
值栈应用:
 *context:
    统一管理了三大作用域,操作任意作用域,直接使用ValueStack对象
*ValueStack对象通过context,提供了另外的操作作用域的机制.
 *root
    在一个请求中,共享了Action实例中的属性,进而实现了一个请求内部的数据传递
替代了request作用域
==========================================================================================
struts2标签
   *struts2标签中所定义的OGNL,上下文默认是ValueStack对象中的context,根默认是ValueStack对象中root中存  放的Action实例对象
   1.显示单个值:
       <s:property  value="OGNL"/>
   2.有条件的显示值:
       <s:if test="">
     
  </s:if>
       <s:elseif test="">
  
  </s:esleif>
  <s:else>
  
  </s:else>
    3.显示多个值
  <s:iterator value="OGNL" status="sta" var="va">
      <s:property value="#va.XXX">
  </s:iterator>
  *其中va会临时存储在ValueStack的context中,遍历完毕时则销毁
  *status
     sta.count 返回当前遍历是第几次
          sta.index 返回当前遍历的索引
 sta.odd  返回当前遍历是不是第奇数次(从1开始)
 sta.even  返回当前遍历是不是第偶数次(从1开始)
  
  
  *技巧:<s:iterator 每次遍历的的对象,会被临时放到ValueStack的栈顶
   且<s:property/> 会取出ValueStack的root的栈顶元素













==========================================================================================
工具类:
   *ServletActionContext
        ServletActionContext.getRequst();
                   .getResponse();
..
   *ActionContext   
        ActionContext ac=ActionContext.getContext();
        ValueStack vs=ac.getValueStack();
   
   
   
   
   
===========================================================================================
请求:
A  VsA
B  VsB
C  VsC


<c:forEach items="${requestScope.emps}" var="emp">
<tr class="row1">
<td>
${emp.id}
</td>
<td>
${emp.name }
</td>
<td>
${emp.salary }
</td>
<td>
${emp.age }
</td>
<td>
<a href="emplist.html">delete emp</a>&nbsp;<a href="updateEmp.html">update emp</a>
</td>
</tr>
</c:forEach>


<s:iterator value="emps" var="emp">
<tr class="row1">
<td>
<s:property value="#emp.id"/>
</td>
<td>
<s:property value="#emp.name"/>
</td>
<td>
<s:property value="#emp.salary"/>
</td>
<td>
<s:property value="#emp.age"/>
</td>
<td>
<a href="emplist.html">delete emp</a>&nbsp;<a href="updateEmp.html">update emp</a>
</td>
</tr>
</s:iterator>


*方法拦截器:Interceptor
   相对于(类)拦截器,拦截粒度更小,更精确,基于Action中的某些方法进行拦截。
*编码流程:
  1.定义
     public class MyMethodInterceptor extends  MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation arg0) throws Exception {
return null;

}
  2.配置--和(类)拦截器一样
    *声明
*引用
<interceptors>
<interceptor name="min" class="com.day6.method_interceptor.MyMethodInterceptor">
<param name="includeMethods">mehodInter,methodInter2</param>
</interceptor>
<interceptor-stack name="mins">
<interceptor-ref name="min"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="mins"></default-interceptor-ref>


<interceptor name="min" class="com.day6.method_interceptor.MyMethodInterceptor">
<param name="excludeMethods">methodInter2</param>
</interceptor>
<interceptor-stack name="mins">
<interceptor-ref name="min"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
================================================================================================
自定义结果类型
 *dispatcher/redirect/chain/redirectAction
 *图片,pdf....
 
 *编码流程:
    *pdf
*验证码
    1.定义类
       public class MyResult implements Result{

/**
* @描述:向用户输出的内容
* @ActionInvocation ai
*                  1.ai.getStack();
*                    等效:
*                     ActionContext ac=ai.getInvocationContext();
  ValueStack vs=ac.getValueStack();
*/
public void execute(ActionInvocation ai) throws Exception {
HttpServletRequest req=ServletActionContext.getRequest();
HttpServletResponse res=ServletActionContext.getResponse();
//
res.sendRedirect("/struts_day6/index.jsp");
}


}
    2.配置
  *声明
      <result-types>
<result-type name="myret" class="com.day6.result.MyResult"></result-type>
  </result-types>
  *引用
           <result name="okret" type="myret"></result>

































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值