zoukankan      html  css  js  c++  java
  • Java框架之Struts2(一)

    在学习Struts2之前,我们要知道Java为什么要有反射机制呢?反射机制可以说是填补Java不能动态访问某一个类的空白。利用反射机制,动态的创建一个对象。动态的访问类的某个属性,而且访问哪一个属性自己可能还不知道,只能通过有个变量进行访问。

    一、反射

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    Java反射机制主要提供了以下功能:

    1.在运行时判断任意一个对象所属的类;

    2.在运行时构造任意一个类的对象;

    3.在运行时判断任意一个类所具有的成员变量和方法;

    4.在运行时调用任意一个对象的方法;

    5.生成动态代理。

    Java 中反射相关的类,都在 java.lang.reflect 包下,主要有以下几个类

    Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。

    Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。

    Constructor <T> 提供关于类的单个构造方法的信息以及对它的访问权限。

    java.lang 包下的 java.lang 类 Class<T>

    Class 类的实例表示正在运行的 Java 应用程序中的类和接口。

    枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。 注意:可以这样 int.class

    //例一 通过调用无参构造函数,创建对象
              public class Test {
                    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
                        Dog dog=(Dog)createObj(Dog.class);
                        dog.shout();
                        
                        Cat cat=(Cat)createObj(Cat.class);
                        cat.shout();
                
                    }
                    
                    //这个方法用来创建类的实例
                    static     Object  createObj(Class clazz) throws InstantiationException, IllegalAccessException{
                        return clazz.newInstance();  //创建对象(注意:它是调用对象的构造函数(无参))
                    }
                }
                
                
                class Dog{
                    public void shout(){
                        System.out.println("汪汪");
                    }
                }
                
                class Cat{
                    public  void shout(){
                        System.out.println("喵喵");
                    }
                }
        //例二 调用带参的数构造函数
                     class Dog{
                            private String dogName;
                            public Dog(String dogName){  //有了一个有参的构造函数,就没有无参的构造函数了
                                this.dogName=dogName;
                            }
                            public void shout(){
                                System.out.println("汪汪 我的名字是"+this.dogName);
                            }
                        }
            
                        static Object createObj(Class clazz) throws  Exception{
                            // return clazz.newInstance();  这样不可以
                             Constructor con=clazz.getConstructor(String.class);//它的参数是这样声明的 Class ... parameterTypes
                             Object obj= con.newInstance("tom狗");  //Object ... initargs
                             return obj;
                        }
                    
                     public static void main(String[] args) throws Exception {
                            Dog dog=(Dog)createObj(Dog.class);
                            dog.shout(); //汪汪 我的名字是tom狗
                     }
          //例三 方法的调用
          class Dog{
                private String dogName;
                public Dog(String dogName){  //有了一个有参的构造函数,就没有无参的构造函数了
                    this.dogName=dogName;
                }
                public void shout(){
                    System.out.println("汪汪 我的名字是"+this.dogName);
                }
                
                public void shout(String content){
                    System.out.println(content);
                }
                
                public void shout(String content,int age){
                    System.out.println(content+"  我的年龄是:" +age);
                }
                
                public void eat(){
                    System.out.println("小狗正在吃东西");
                }
            
            }
        
          //动态调用类对象中的方法
            //ojb 代表要被调用方法的对象
            //methodName 代表要被调用的方法
            static void invokeTest(Object obj,String methodName )throws Exception {
                //Method [] methods=obj.getClass().getDeclaredMethods(); //取得所有方法,但除了继承来的
                //Method [] methods=obj.getClass().getMethods(); //取得所有公共方法,包含继承来的
                
                /*for(Method m: methods){
                    System.out.println(m.getName());
                }*/
                
                
            /*    Method  m=obj.getClass().getMethod(methodName, String.class); //第二个参数 :Object ... parameterTypes
                m.invoke(obj, "这是做为一只狗想说的话");*/
                
                Method  m=obj.getClass().getMethod(methodName, String.class,int.class);
                m.invoke(obj, "这是我的另一句话",2);    
            }
            
            public static void main(String[] args) throws Exception {
                    Dog dog=(Dog)createObj(Dog.class);
                    invokeTest(dog,"shout");
            }
          //例四 属性的调用   Field
              static void fieldTest(Dog dog)throws Exception{
                        //Field [] filedList=dog.getClass().getFields() ; //取得所有的公共字段,包含继承来的
                        Field [] filedList=dog.getClass().getDeclaredFields(); //取得所有的字段,除了继承来的
                        
                        for(Field field : filedList){
                            System.out.println(field.getName());
                            System.out.println(field.get(dog));   //注意,这里要把 类对象传进去 Field 才知道要访问哪个类对象的属性
                        }
                }
                
                class Dog{
                public  String dogName ="tom";
                public int age=90;
              }
          
           main 方法 :
           {
               Dog dog=(Dog)createObj(Dog.class);
               fieldTest(dog);
           }

    二、Struts2 简介

    Struts 2 是在 struts1 和 WebWork 的技术基础上进行了合并的mvc 框架,其全新的 Struts 2 的体系结构与 Struts1 的体系结构差别巨大。Struts2 以 WebWork 为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts2 可以理解为WebWork的更新产品。虽然从Struts1 到Struts2 有着太大的变化,但是相对于WebWork,Struts2 的变化很小

    为什么要使用 struts2 呢?

    传统的MVC模式的问题, 主要就是以下操作有重复性。

    重复性一:得到请求参数 Servlet 中

    String userName=request.getParameter("userName");
    String password=request.getParameter("password");
    UserInfo user=new UserInfo();
    user.setUserName(userName);
    ....       

    重复性二:请得到的请求参数进行类型转换

    int id=Integer.parseInt(request.getParameter("id"));

    重复性三:对请求参数的校验 (服务端)

    重复性四:请求的跳转 ... request.getRequestDispatcher("xxx.jsp").forward(reques,response)

    常用的 MVC 框架

    struts1

    struts2

    spring mvc

    jsf (sun 公司提供的mvc 规范

    三、Struts2环境的搭建

    在struts2的开发包中,有四个文件夹,和一些文本的授权文件

    apps, docs, lib , src

    apps:示例程序

    --struts2-blank.war //空的struts应用
    如何搭建一个最最简单的Struts2的项目;它还会告诉你,Struts2至少需要依赖哪些jar包 (请以后不要再为jar包错误而苦恼);同时,也给你做出了一些范例,web.xml怎么写,struts.xml又怎么写。
    --struts2-mailreader.war //给出了注册流程、以及发邮件功能
    --struts2-portlet.war // 则给出了在Portal环境下的Struts2的应用
     // Portal是一个基于web的应用程序,它主要提供个性化、单点登录、
    // 不同来源的内容整合以及存放信息系统的表示层。
    --struts2-rest-showcase.war  //rest是 针对WEB 提出的一种构架风格  和 SOAP (简单的对象访问协议)是并列的概念
    --struts2-showcase.war

    Struts2的特性的大杂烩,这对于你看reference是相当有帮助的。比如说,当在看文档时看到了"文件上传"的章节,那么你就可以参考项目中的upload子目录。相当于你一边看文档,一边已经有一个现成的跑得通的例子在这里提供给你。

    docs:文档,API 和相关的指南 (Guide)

    注意,要从home.html 开始,过去的版本 是 index.html,现在换了

    lib:jar

    src:源码
    四、开发struts依赖的jar

    ==最少的配置:
    struts2-core-2.x.x.jar : Struts2 框架的核心类库
    xwork-2.x.x.jar XWork类库,Struts 在其上构建
    ognl-2.6.x.jar 对象导航语言(Object Graph Navigation Lanaguage) Struts2 框架使用的一种表达式语言
    freemarker-2.3.x.jar Struts2 的 UI标签模板 使用 freeMarker 编写
    commons-logging-1.1.x.jar  ASF 出品的日志包,Struts2 框架使用这个日志包来支持log4j 和 jdk1.4+的日志记录
    Commons-fileupload

    ==还有一种最省事的方法:

    如果不需要跟第三方框架集成,把不带-plugin 结尾的jar文件都添加到类路径即可,反之要加入对应的 plugin.jar文件,例如 和 spring 的集成,需要加入 struts2-spring-plugin-2.x.x.jar

    ==或者是把 struts2-blankWEB-INFlib 下所有的 jar 都导入
    --asm-3.3.jar  //小巧轻便的 Java 字节码操控框架 ,它能方便地生成和改造 Java 代码。 Hibernate 和 Spring 在底层都用到了 ASM(CgLib 底层用的 asm)
    --asm-commons-3.3.jar  //提供了基于事件的表现形式
    --asm-tree-3.3.jar //提供了基于对象的表现形式
    --commons-fileupload-1.3.1.jar //Struts文件的上传下载
    --commons-io-2.2.jar  //apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件,url源代码等
    --commons-lang3-3.1.jar //用来处理Java基本对象方法的工具类包,可以简化很多平时经常要用到的写法,例如判断字符串是否为空等等。
    --commons-logging-1.1.3.jar //提供的是一个日志(Log)接口(interface)
    --freemarker-2.3.19.jar //是一个模板引擎,一个基于模板生成文本输出的通用工具,更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库
    --javassist-3.11.0.GA.jar //(JAVA编程助手)使Java字节码操纵简单。这是一个编辑Java字节码的类库。
    --log4j-1.2.17.jar //非常强大的log记录软件
    --ognl-3.0.6.jar //对象图导航语言,是一种功能强大的表达式语言
    --struts2-core-2.3.16.1.jar //核心包
    --xwork-core-2.3.16.1.jar //webwork的核心包,因为struts2的前身是webwork

    五、搭建Struts2 的初始环境:

    1) 导包

    appsstruts2-blankWEB-INFlib 下所有的jar包

    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>

    3) 建一个struts.xml 文件,放到src目录下即可

    内容如下 是空的

    <?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>
                                
    </struts>

    4) 布署项目,如果启动没报错,则环境搭建成功      

    六、第一个struts2 应用

    1)

    login.jsp
          <form action="gogogo" method="post">
                账号:<input type="text" name="userName" />
                密码:<input type="text" name="password" />
                <input type="submit" value="提交" />
                ${msg }
            </form>

    2)

     //在工程中建 cat.action这个包,然后在包下建 UserAction 这个类
           //这个 UserAction 就是个普通类
              public class UserAction  {
                    private String userName;  //一定要和form表单中的字段同名
                    private String password;
                    private String msg;
                    .. 要生成 get set 方法
                
                    //方法的返回类型必须String 型,方法名任意
                    public String execute(){
                        UserInfo user=UserDao.getLoginUser(userName,password);
                        if(user!=null){
                            msg="用户名和密码正确,OK";
                            return "my_success" ;  //视图
                        }
                        
                        else{
                            msg="用户名或密码错误 Error";
                            return "my_error"; 
                        }
                    }

    3)

    <?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>
                <package name="packageOne" namespace="" extends="struts-default">
                    <action name="gogogo" class="cat.action.UserAction"  method="execute" >
                        <result name="my_success">/main.jsp</result>
                        <result name="my_error">/login.jsp</result>
                    </action>
                </package>
            </struts>

    注意

    1) execute 这个方法, 它的名字可以是任意的,如果就叫 execute ,则在配置文件中,不用指定 method

    2) 方法的返回值必须是String

    3) 要传值的属性必须有 get set 方法

    总结 struts2 的开发流程

    1) 定义能发送请求的页面,这个页面要么包含表单,要么包含超链接,个另情况可以不用(比如用javasript发请求,或从地址栏直接访问)

    2) 定义处理请求的 action

    3) 在配置文件中,配置 请求 和action的对应关系, 还要配置处理结果和物理视图之间的对应关系

    4) 编写视图 (通常是jsp 或 html 等)

    对于Action 的说明

    对于  Action  struts2 没有太多的要求,但通常建议

    1) 实现Action接口 ,或 者继承自 ActionSupport 类(这个类实现了 Action 这个的接口),它增加了一些类型转换,输入输出校验等支持,而且它实现了execute这个方法,该方法直接返回 SUCCESS

    2) 为每个请求参数都提供一个 field ,并提供get 和 set 方法 , 为传递的结果也定义field ,并提供get 和 set 方法

    3) 提供一个无参的,返回值为String型的 execute 方法

    对于配置文件中的Action 的配置

    1) 要求所有的Action都在包中 (package)

    2) action 元素通常用如下配置

    -- name //皀定action处理哪个请求,也就是请求的名称 ,(gogogo)

    -- class //指定action对应哪个类,

    -- method //指定avction类中用哪个方法来处理请求

    七、继承 ActionSupport 的Action 类

    ==GoodsAction ==

    public class GoodsAction extends ActionSupport {
                    private GoodsDao _dao=new GoodsDao();
                    private GoodsInfo goodsInfo;
                    
                    public String execute(){
                        if( _dao.addGoods(goodsInfo)==1)
                            return SUCCESS;
                        else{
                            return ERROR;
                        }    
                    }

    == goods_add.jsp===

    <form action="goods/goodsAction" method="post">
               商品名称:<input type="text" name="goodsInfo.goodsName" />
               商品单价:<input type="text" name="goodsInfo.price" />
               商品描述:<input type="text" name="goodsInfo.des" />
               商品单位:<input type="text" name="goodsInfo.unit" />
               <input type="submit" value="添加" >
           </form>

    ==配置文件==

    <package name="pacakgeTwo" namespace="/goods" extends="struts-default" >
            <action name="goodsAction" class="cat.action.GoodsAction" method="execute" >
                <result name="success">/WEB-INF/goods_manage.jsp</result>
                <result name="error" >/error.jsp</result>
            </action>
        </package>

    本例的知识点:

    1) 可以使用对象传参,在页面用 goods.goodsName 这样的方式命名

    2) extends ActionSupport

    3) action 的配置文件中的namespace 的使用

    4) 可以把内容放在WEB-INF下,这样可以防止客户端直接访问,只能由服务端进行跳转

    例子:商品查询功能

    //在 goods_manage.jsp 中
              <a href="${pageContext.request.contextPath }/goods/listgoods" >查看所有商品</a>
              
                 public class GoodsAction extends ActionSupport {
                        private GoodsDao _dao=new GoodsDao();
                        private GoodsInfo goodsInfo;  //这个是用来做商品添加的
                        private List<GoodsInfo>goodsList;
                        
                        //添加商品
                        public String execute(){
                            if( _dao.addGoods(goodsInfo)==1)
                                return SUCCESS;
                            else{
                                return ERROR;
                            }    
                        }
                        
                        //查询所有商品
                        public String listGoods(){
                            goodsList=_dao.getGoodsList();
                            return SUCCESS;
                        }
    //在配置文件
                     <package name="pacakgeTwo" namespace="/aaa/bbb/ccc/goods" extends="struts-default" >
                            <action name="goodsAction" class="cat.action.GoodsAction" method="execute" >
                                <result name="success">/WEB-INF/goods_manage.jsp</result>
                                <result name="error" >/error.jsp</result>
                            </action>
                            
                            <action name="listgoods" class="cat.action.GoodsAction" method="listGoods" >
                                <result name="success" >/WEB-INF/goods_list.jsp</result>
                            </action>
                        </package>
    goods_list.jsp
    
                <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
                <%@ taglib uri="/struts-tags" prefix="s" %>
                   ...
                  <body>
                  <table width="80%" border=1 cellspacing="0">
                      <c:forEach var="goods" items="${goodsList}"> 
                      <tr>    
                          <td>
                              ${goods.id}
                          </td>
                          <td>
                              ${goods.goodsName}
                          </td>
                          <td>
                              ${goods.unit }
                          </td>
                          
                          <td>
                              ${goods.price }
                          </td>
                          <td>
                              ${goods.des}
                          </td>
                      </tr>
                      </c:forEach>
                
                  </table>
                  
                        // 用 struts 标签 方式一
                      <s:iterator var="goods" value="goodsList">
                          ${goods.id } | ${goods.goodsName }  | ${goods.des } | ${goods.price } <br />
                      </s:iterator>
                      <br>
                      
                       // 用 struts 标签 方式二
                   <s:iterator  value="goodsList">
                          ${id } | ${ goodsName }  | ${des } | ${price } <br />
                      </s:iterator>
                  </body>
                </html>

    总结:

    1 该例继承自 ActionSupport 类,通常action都要继承自该类,以获得一些Struts提供的功能

    2 Action中的 Field 是对象类型,所以form表单中的字段,也是 对象.属性这样的写法

    3 它自动完成了类型转换

    4 jsp文件(或其他 html等) 放在 WEB-INF 文件夹中,安全性更高

    5 可以指定Action namespace 属性

    6 namespace ,存在搜索顺序的问题,其规则如下:

    1) 获得请求路径的URL 例如URL 是 http://localhost:8080/StrutsTest/p1/p2/p3/hellow.action

    2) 先按长的路径,在 p1/p2/p3 下找有没有 namespace= p1/p2/p3的 package ,有这个package的话,则找pacakge里有没有名字为hellow的Action

    如果没有这个package的话,则去默认 namespace的 package里去找

    3) 如果没找到 namespace= p1/p2/p3的 package ,则递减,找 names民pace  =p1/p2/的包

    4) 以此类推

    原则 : 不管有没有.只要找到包了,就不递减了

    什么是默认 namespace 的 package ? 就是 不指定namespace 或指定 namespace="" 的包

    7 请注意 url 的写法    <a href="${pageContext.request.contextPath }/goodsManage/listGoods" >

    实际上,对请求的路径,经常要进行这样的处理 包扩 form表单的 action 属性也这样写

    附: 如何在编写 struts.xml的时候能出现提示?

    在 这个配置文件的上面,可以看到有对dtd 文件的引用

    <?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 提供的包中,搜索 struts-2.3.dtd 这个文件,找到后,复制出来放到一个地方
    然后 点击 windows -> prefrences ->Myeclipse ->Files and Editors ->XML ->XML Catalog 点击右边的 add 按钮,
    在弹出的对话框中, 上面的location 选刚才放置的struts
    -2.3.dtd文件的位置,
    下面的 Key type 中选 uri,key的值输入 http:
    //struts.apache.org/dtds/struts-2.3.dtd ,点击 ok 即可,一般来说要重启这个 struts.xml文件

    附:   折叠代码插件 code folding 使用方法

    解压后,把com.cb.eclipse.folding_1.0.6.jar复制到MyEclipse 8.5dropins包下面

    重启 myeclipse

    点击Window > Preferences > Java >Editor>Folding ,进行设置,使用的时候:

     /_start
         public String nihao="nihao";
         public String tahao="tahao";
          //_end  
    
  • 相关阅读:
    一场由空格引发的错误数据
    ECS服务器搭建Discuz 邮箱设置,报错处理
    MS SQL CASE WHEN 的用法
    sql prompt 缩写 快捷键
    CentOS 防火墙
    docker swarm
    docker machine
    docker-compose 配置
    docker-compsoe & .netcore & nginx
    dockerfile
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/8067229.html
Copyright © 2011-2022 走看看