• Struts2学习笔记三:深入Action


    一:Action中获取参数值

        在Servlet中,我们通过doGet()/doPost()方法中的参数,获取request/response对象,然后提取参数值;

        处理请求结束后,有数据需要携带返回客户端时,servlet中是通过request.setAttribute()的方式携带属性值返回客户端。

        而在Action中,提供了三种方式获取参数、返回结果:

        1:Action全局变量法

        在Action中定义一系列全局变量,以及它们的getter/setter方法。则在请求分发到action时,会自动提取request中的同名参数值,注入到action实例的全局变量中。

        action返回result时,Structs2默认全局变量值都内置到了request中了,只需转发request到结果页面,在结果页面通过EL表达式,根据参数名获取值即可。

        2:面向对象思想接收参数(用此方法则不能用法一

         如果action需要接收的参数比较多时,需要借助MVC架构中的VO对象思想。

         此时,我们可以定义一个实体类 xxVO,实体类中定义一系列属性,对应客户端需要传递过来的值,并定义每个属性的getter/setter方法。

         然后,在action中,我们只需引入一个xxVO的成员变量并定义其setter、getter方法即可,然后在action中通过 vo.getXX() 使用参数。

         最后,我们在页面端通过 参数名 来为vo对象的属性进行赋值:如:<input name="vo.属性名">

         在接收到请求后,Structs2会自动根据参数名,创建一个vo对象调用setter方法把属性值赋值,然后把vo对象注入到action中。

         返回结果数据同法1,此action中的属性变量均可以在页面端以EL表达式获取。

         3:优化法2——实现ModelDriven接口

         法2中,页面端参数名需要使用 vo对象名.属性名  的格式,这样如果action中的vo对象名改变的话,页面端参数名都需要更改,比较麻烦。法3可以解决这个问题。

         定义action时,实现ModelDriven接口;

         声明并通过new VO()实例化vo成员变量;//注意:这里是使用new实例化变量,不是注入。

         最后,在页面端,参数名只需与vo类中的属性名相同即可,无需指明是action中哪个vo对象的哪个属性。

        

         页面端的参数,可以通过 []运算符、 点运算符进行复杂的参数赋值,如:为action中的list对象的元素赋值,可以:name="list[i].vo.属性名" 这样赋值。

    二:Action中获取request、response、application等对象

        有些情况下的确需要用到request、response、application等对象时,可以在定义action时实现资源接口xxxAware来达到。

        定义Action时,实现RequestAware/SessionAware/ApplicationAware接口,并在Action中定义相应类型的变量,如:HttpSession session;然后实现接口的方法setXX(){this.XX=XX;}即可把相应的Servlet内置对象获取到action中来使用。

    三:Action命名空间影响action的搜索

        客户端请求action的url的格式为:web项目url+命名空间+action名

        命名空间是为了模块化地管理action而配置的package属性,提供精准的action匹配,所以客户端应该严格按照正确的路径来编写URL。

    四:配置Action的动态方法调用——通配符法

       通常,我们把Action作为模块的单位,即:一个模块的所有请求处理都在一个action中处理,如:登录模块的相关请求都在loginAciton中定义方法来处理。但是,我们在配置action时,默认是执行action的execute()方法,如果需要调用其他方法,则需要为每种情况配置一个action标签,十分麻烦。

       Structs2提供了一种通配符的方法,根据客户端传过来的URL内容,动态地匹配具体的action、具体的方法。

       action标签的name属性:采用 * 代替具体内容,采用 _ 作为间隔。

       URL的拼写:用 _ 作为间隔,指明具体的url。

       在class属性值、method属性值、<result>标签内容等地方:采用 {x} 获取name属性值中 第几个* 的值作为具体值,动态匹配具体的action、方法、以及页面响应。

    五:默认action  

        当用户输入了非法的url时,由于服务端没有对应的资源可以响应,就会返回404错误或者跳转到报错页面,这样用户体验是非常差的。因此,我们可以定义一个action,默认返回一个友好的ERROR提示页面。然后在structs.xml中配置默认action,引用该错误提示action进行返回。

    六:后缀配置

        Structs默认使用action处理请求,action的是 .action 后缀的文件,因此可以不写后缀编写url。如果需要使用其他后缀,如:.do、.html、.jsp等(注:这里是指使用这些后缀,而非真正的使用这些类型的文件。如:处理登录页面的loginAction类,配置扩展后缀 .jsp,则核心控制器获取到请求后如果是loginAction.jsp则仍然是把请求分发给loginAction而不是login页面)

    <constant name="struts.action.extension" value="action,do,..." />

    七:action结果响应

       1:结果集

        Action默认封装了一些字符串常量,表示某种结果类型。Structs2根据结果字符串进行不同的响应,这些都是通过<result>标签来配置的。

        <result>默认结果是SUCCESS,当action返回结果是SUCCESS字符串时,重定向到标签间页面。

        我们可以通过name属性值,配置不同返回结果的响应内容:

        除此之外,我们也可以返回自定义的字符串,只需配置好name属性为返回结果字符串的result标签即可。

        2:返回结果——INPUT

        上面5个返回值中,INPUT比较特殊,它是Structs提供给我们的礼物之一——INPUT结果值表示自动返回前一个接收输入的页面,并保留了原先接收到的输入内容。

         比如:登录页面接收username和password,传递给loginAction;若发现密码错误,需要返回登录页面时,action返回INPUT结果,则Structs2自动跳转到login页面,并保留原来输入的username和password内容在输入框内。

         这样做的好处是,当某一些需要接收很多输入的页面(如:注册)传递过来的参数有少数没通过验证时,用户无需重复进行大量输入,只需修改部分不符合要求的输入即可。

         有两种方法使用INPUT:

         1)在action的普通方法中,如果验证不通过,则显式 return INPUT;

         2)重写validate()方法,如果验证不通过,则添加错误信息(见下面第八点);在方法结束前,会自动检查错误信息map,如果不为空则说明验证不通过,自动返回INPUT。

       

         3:全局结果

         全局结果:放在action标签之外配置,在同一package内的所以action都可以使用这个结果,通常用来配置一些共用的结果值,如:404

         4:结果响应方式——type属性

         result标签的type属性定义了以什么样的方式来响应,重定向?还是转发?还是其他?默认是内部转发dispatcher。

         type属性有以下几种:

        chain:用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息.

        dispatcher:用来转向页面,通常处理JSP.

        freemaker:处理FreeMarker模板.

        httpheader:控制特殊HTTP行为的结果类型.

        redirect:重定向到一个URL,被跳转的页面中丢失传递的信息,如request.

        redirectAction:重定向到一个Action,跳转的页面中丢失传递的信息.

        stream:向浏览器发送InputSream对象,通常用来处理文件下载,还可用于返回AJAX数据.

        velocity:处理Velocity模板.

        xslt:处理XML/XLST模板.

        plainText:显示原始文件内容,例如文件源代码,相当于out.write()

       redirect和redirectAction的区别:前者跳转到一个页面,后者跳转到一个action。

    八:错误信息

          在Servlet编程中,服务器端校验不通过时,是通过 out.write()方法输出错误信息到客户端的,十分麻烦,还需要自己拼接前端页面代码。

          在Struts2中提供了一个错误信息map,以键值对的方式添加错误信息;在页面端,通过structs2的标签,用key获取具体的错误信息内容即可,十分方便。

          1:在action中添加错误信息,如:

          2:在页面端使用标签获取错误信息

          首先,引入标签库

         然后,通过 name属性获取错误信息

  • 相关阅读:
    使用最小花费爬楼梯
    AVAudioPlayer 如何在页面呈现之后按需初始化
    给 UILabel 中的文字增加 line-through / Strikethrough (删除线)样式
    如何在普通 UIViewController 中使用 UITableView
    如何修改 UINavigationController、UINavigationBar 中 navigationItem 左侧 “返回” 按钮的名称
    在 UIViewController 中手动增加 TableView 出现 Type 'SomeViewController' does not confirm to protocol 'UITableViewDataSource' 问题的解决办法
    iOS 8 录音重放出现 OSStatus error 1685348671 / 2003334207 问题的解决办法
    performSegueWithIdentifier 不生效的解决办法
    AutoLayout 根据文字、图片自动计算 UITableViewCell 高度
    iOS7 UITableView Row Height Estimation
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6808030.html
Copyright © 2020-2023  润新知