A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

就业班_JavaEE_day36_38_struts2

一框架概述
    半成品、少写代码、提高效率、节约成本
    常见框架: SSH   SSM
    二种开发方式:xml配置文件;注解(常用)
    xml作用:
        1 数据的存储(现在有数据库代替)
        2 作为数据协议进行传输(xml/json)
        3 作为配置文件
    dtd xsd
        
二 开发流程
    1 导包 可以从blank项目中进行拷贝
    2 在web.xml中添加strutsprepareandexecutefilter
        过滤器在服务器启动时就创建,并调用init方法,struts中的该过滤器主要用来加载struts自带的配置文件和struts.xml核心配置文件。
    3 创建action  有三种方式     
        A 普通类 public String execute() {}
        B  实现Action接口  并实现接口中的execute方法
        C 继承ActionSupport类
        【通常采用第三种方式】。 action中不指定method,默认访问execute方法。actionsupport的execute默认返回success
    4 在struts.xml中配置action
       structs2 核心配置文件 struts.xml  放在src下  该文件的名称和位置固定。
     
       action有三种配置方法
       A method
           <action name="action名字 ,自定义" class="action类全路径" method="action中的方法名">
           该方式的缺点是:action类中的方法过多时,将配置多个action。一个方法对应一个action配置
       B 通配符 *   【通常采用该方式】
          eg: <action name="customer_*" class="action类全路径" method="{1}">
          *代表任意,上述写法能匹配任意以customer_开头的访问路径    meithod中{1} 表示占位符,1表示第一个* 。 * 可以写多个,对应method中占位符可以有多个。
      C 动态方法
          该方法了解,一般不使用。user!add   useraction中的add方法
         
        <struct>
                <package name="包名称,自定义,要唯一" extends="struts-default"  namespace="/"> // extends中的内容固定  
                        <global-result> //全局result
                        <action name="action名字 ,自定义" class="action类全路径" method="">
                                <result name="aciton中方法的返回值" type="默认是转发,可以配置为重定向">XXX中间写转发或者重定向的路径</result>
                        </action>
                </package>
       </struct>
       补充:可以通过在struts.xml中通过include 其它的xml,来实现分模块开发。
       package中namesapce不写默认是"",表示任意路径下都可以访问action。如果要配置namespace的话,必须以/开头。
       可以配置为/ 或者 /xxx 或者/xxx/yyy 通常package的name和namespace都用模块名来定义。
      
三 Action中的result配置
      1 全局result <globe></globe>中定义result ,需要注意全局的范围只在一个package中有效。
      2 局部result  写在action中的就是局部result   如果有同name的,以局部的为准
      3 result type 属性  默认是dispatcher   可以配置成redirect
          dispatcher 和 redirect 都是针对转发或者重定向到jsp页面
          如果是要转发和重定向到action 则使用chain 和 redirectAction 。其中chain不常用。
          CTRL + F5 无缓存刷新

四  Action中如何封装表单数据到实体类中  
     1 原始封装  通过servletActionContext获取到request 一个一个属性进行获取和赋值
     2 struts提供了二种封装表单的方式
       A 属性封装         
          1)在action中定义与表单中同名的成员属性,并提供getset方法。
          2)在action类中申明实体类,并提供getset方法。 在form表单中  <input  type="text" name="user.username"> 对name属性进行表达式定义
       B 模型驱动封装   action类通过实现modeldriven接口实现          【通常采用这种方式】。eg:
          DemoAction  implements  ModelDriven {
               User form = new User();
               public  User getModel(){
                    return form;
               }
          }
        补充:
        属性封装和模型驱动封装针对同一表单不能同时使用,如果同时使用,则只有模型驱动封装有效。但是对于不同的表单,可以同时使用。   
        模型封装和属性封装的区别:
            模型封装只能封装一个实体bean,因为实体bean类型在ModelDriven接口泛型中已规定   
             而表达式封装可以封装多个实体bean 。通过在form中name属性的表达式指向不同的实体bean <input  type="text" name="book.bname">
              
五 Action中的常见API
     1 ActionContext    通常通过ActionContext.getContext().getValueStack()来获取值栈
     2 ServletActionContext     
         getRequest()  可以得到HttpServletRequest   
         有了request就可以得到HttpSession     
         getServletContext()     可以得到ServletContext     
     3 接口注入 ServletRequestAware  可以通过该方式获取到request
      
六 值栈和OGNL
    作用: 值栈用来存值,OGNL结合struts标签来取值。
    值栈数据结构:
    可以通过<s:debug> 来查看 ,主要包含root(root是对象栈)和context(context是一个map),通常我们使用root来存取值。
    root对应于ognl中的根  , context对应Ognl中的非根。所以取root中的值不用加#号 ,取context中的值需要加#号
    OGNL语法:
    # 表示从context中取值
    %{} 用于struts的表单标签中,从值栈中取值,%{}
    ${} 用于在配置文件比如struts.xml中从valuestack中取值。
   
     一个request对应一个action,对应一个actioncontext,对应一个valuestack,action是多实例 。
     valuestack保存在request域对象中,所以只能在转发中使用。

     如何向值栈中存值 ,有如下三种方式:
     1  通过ActionContext 获取到ValueStack对象,然后调用valuestack的set方法设置。 会在栈顶上开辟一个Map 【通常采用这种方式】,因为有key值。
     2  通过ActionContext 获取到ValueStack对象,然后调用valuestack的push方法设置。会在栈顶上开辟一个List
     3  通过在action中定义一个成员变量,并提供该成员变量的get方法,在action类中的方法中对成员变量赋值,则将值添加进值栈,并且不会在栈顶开辟新空间,
         而是将值放在栈顶的action引用。
         
    如何从值栈中取值:
      先在jsp中引入struts标签  <%@ taglib uri="/struts-"  prefix="s" %>
      然后通过<s:property value="OGNL"> 来获取值。
      1 取一个字符串
       <s:property value="字符串变量的名称"/>    eg <s:property value="username"/>
      2 取一个对象
        <s:property value="成员变量的名称"/>    eg <s:property value="user.username"/>  <s:property value="user.password"/>
      3 取一个list
         有三种取法
            A  <s:property value="list[0].username" /> <s:property value="list[0].password" />
            这种方法的前提是你要知道遍历的list个长度。通常不使用。
            B  <s:iterator  value="list">
                    <s:property value="username"/> <s:property value="password"/>
                </s:iterator>
            这种方法类似与jstl的foreach标签,但是比jstl的foreach少 var属性
            C <s:iterator  value="list" var="user">【通常采用该方式】
                    <s:property value="#user.username"/> <s:property value="#user.password"/>
                </s:iterator>
            #表示从context中取值,因为加了var之后,struts会将user变量临时存放在context的map中,对context的取值需要用#。
            
    补充:
    EL表达式也可以从值栈中取值,因为struts对HttpServletRequest中的getAttribute方法做了增强,当从域对象中取不到值时,会从值栈中取值,并放回域对象中。
    这样el表达式就能从域中取到值。
   
七 struts2-拦截器
    1 拦截器的概念只在struts中存在。它封装了很多功能,struts2中定义了很多拦截器,有一组默认拦截器定义。在struts-default.xml中定义。
        拦截器在action对象创建之后,在执行方法之前,执行。
        拦截器和过滤器的区别:
            过滤器可以拦截任何资源
            拦截器只能拦截action
   
    2 拦截器底层原理
        1 AOP思想 面向切面编程   不改源代码通过配置实现功能的增强       AOP通过动态代理实现。
        2 责任链模式  类似web中过滤链 每个方法执行完成后,必须放行才能执行后续方法。
   
    3 自定义拦截器
         1 创建类继承MethodFilterInterceptor
         2 重写MethodFilterInterceptor中的doIntercept方法
            当满足某个条件是进行放行 return invocation.invoke() 相当于放行。doIntercept方法的返回值,与action中result的name对应。
         3 注册拦截器,通过配置的方式将action和拦截器关联。
             在action所在的package中配置拦截器
             在action中引用
             配置自定义拦截器后,struts2中的默认拦截器将失效,需要手动配置以下。
            
         <package name="包名称,自定义" extends="struts-default"  namespace="/"> // extends中的内容固定  namespace名称空间可以自定义一般写/
                <!-- 自定义拦截器-->
              <interceptors>
                <interceptor name="自定义拦截器名称" class="拦截器的全路径"></interceptor>
              </interceptors>
                <action name="action名字 ,自定义" class="action类全路径" method="">
                        <!-- 在action中引用自定义拦截器-->
                         <interceptor-ref name="自定义拦截器名称"">
                                <param name="excludeMethods">action中不需要拦截的方法名称,如果有多个,用逗号进行隔开</param>//excludeMethods 这个名字固定
                         </interceptor-ref>
                         <!-- 在action手动配置下默认拦截器,使默认拦截器也起作用-->
                         <interceptor-ref name="defaultStack"></interceptor-ref>
                        <result name="aciton中方法的返回值" type="默认是转发,可以配置为重定向">XXX中间写转发或者重定向的路径</result>
                </action>
               
                <!-- 另外一种写法 设置缺省拦截器 只在当前package下有效-->
                <interceptors>
                    <interceptor name="logininterceptor"
                        class="com.itheima.strtus2.web.interceptor.LoginInterceptor">
                    </interceptor>
                    <interceptor-stack name="myStack">
                        <interceptor-ref name="logininterceptor"></interceptor-ref>
                        <interceptor-ref name="defaultStack"></interceptor-ref>
                    </interceptor-stack>
                </interceptors>
                <default-interceptor-ref name="myStack"></default-interceptor-ref>
        
        </package>
        
        <default-interceptor-ref name="myStack"></default-interceptor-ref>可以用来指定package中的action的默认拦截器
        在action中不显示指定 <interceptor-ref > 则action会使用默认拦截器defaultStack。
        
         4 可以通过配置不拦截action中某些方法,配置方法见上面action中的定义。
         
八 struts2配置文件加载顺序【面试】
    1.default.properties(常量)
    2.struts-default.xml(默认配置) 定义了默认package 默认interceptor 默认class actionsupprot actionsupport中默认execute方法 默认success返回值
    3.struts-plugin(struts插件的配置)
    4.struts.xml(自定义配置)
    5.struts.properties(自定义常量,通常不用,而是在struts.xml中配置)
    6.web.xml

九 struts业务流程
    请求 request  --》 strutsprepareandexecutefilter--》actionmapper--》proxyaction--》actioncontext(interceptor、action)--》interceptor--》action--》result--》interceprot--》response
   
十 文件上传
    form表单 : method=post  enctype=multipart/form-data <input type=file  name=upload/>
    action
    File upload;
    String uploadContentType;
    String uploadFileName;
    多文件
    action
    File[] upload;
    String[] uploadContentType;
    String[] uploadFileName;
   
    配置文件上传默认大小限制;
    配置文件上传类型或者后缀名限制;
    <interceptor-ref name="defaultStack">
                <!-- 允许的文件MIME类型 -->
                <!-- <param name="allowedTypes">image/png,image/jpg</param> -->
                <param name="fileUpload.allowedExtensions">chm</param>
    </interceptor-ref>

十一 注解开发
    导包struts2-convention-plugin-2.3.34.jar   在2.1版本后引入注解
    @Namespace("/")
    @ParentPackage("struts-default")
    @Action(value = "user_login", results = {
            @Result(name = "success", location = "/product.jsp"),
            @Result(name = "error", location = "/login.jsp") })
    插件包中对 action actions struts struts2 package 进行扫描注解。

十二 JSON扩展
     fastjson 阿里     jackson  二个用的比较多的jsonjar包
     通过JsonResult类来封装json返回值。
     public class JsonResult<T> {
        private int status;// json状态 1表示成功,0 表示失败
        private List<T> list; // list表示内容
        private String msg;// 消息描述
    }
    fastjson
    1 fastjson中date 在属性上添加jsonfiled注解来设置样式 @JSONField(format="yyyy-MM-dd")
    2 SerializeFilter filter = new PropertyFilter() {
            //返回true表示不拦截,返回false表示拦截,不显示该属性。
            @Override
            public boolean apply(Object obj, String attr, Object value) {
                //arg0 表示对象 arg1 表示属性名称  arg2 表示属性值
                if(attr.equals("uid")){
                    return false;
                }
                return true;
            }
        };
    3 JSONObject.toJSONString(user,filter)
    4 JSONArray.toJSONString(集合)
   
    jackson
    1 在对象属性上添加jsonignore注解可以过滤掉该属性,不在json中出现。还可以通过编码实现。
    2 设置jackson的data格式
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    3 ObjectMapper mapper = new ObjectMapper();
       String json = mapper.writeValueAsString(对象或者集合);

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马