Struts2实现Preparable接口和【struts2】继承ActionSupport类

Struts2实现Preparable接口  实现preparable接口,实现public void prepare() throws Exception 方法。当你访问某问action指定方法之前,最先执行prepare()。这里边可以写些准备工作的代码

1 public void prepare() throws Exception {
2
3         request = ServletActionContext.getRequest();
4         requestIp = getIpAddr(request);
5         response = ServletActionContext.getResponse();
6         session = request.getSession();
7         application = ServletActionContext.getServletContext();
8     }

View Code

Struts2继承ActionSupport类
1)如果你的Action类是继承自ActionSupport的话,确切的说是重写了execute方法,ActionSupport里的默认实现就是返回"success"视图。因此,你可以不实现execute方法,只要你的struts.xml里有"success"对应的result即可。

2)如果你的Action类没有继承ActionSupport,而你又没有在struts.xml中对应<action>标签中用method属性指定你自己的方法的话,默认就要找execute方法,这时是必须要实现execute方法的,否则Struts2会找不到对应的方法而报错。

不过,大部分情况下都是继承ActionSupport的(比如输入验证、文件上传等功能就要求必须继承)。还有,不管你写没写execute方法,还是可以用<action>标签的method属性指定其他方法的。

在Struts2中,Action可以不实现任何特殊的接口或者继承特殊的类,仅仅是一个POJO(Plain Old Java Object,简单的Java对象)就可以;也可以实现Xwork2中的Action接口;但是由于Xwork的Action接口非常简单,为程序员提供的帮助有限,因此,在实际开发中,会更多的使用继承ActionSupport类来实现Action的方式,如下所示:

import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction extends ActionSupport {
    //省略了
}  

  ActionSupport类本身实现了Action接口,所以继承ActionSupport类就相当于实现了Action接口。除此之外,ActionSupport类还实现了其它几个接口,来为程序员提供更多使用的功能,这些接口和Struts2的一些其他特性相结合,可以实现基本的数据验证功能和国际化。接口如下所示:

com.opensymphony.xwork2.Validateable;  //提供validate()方法来为Action增加验证的功能
com.opensymphony.xwork2.Validateaware; //提供方法来保存和恢复action或field级的错误信息
com.opensymphony.xwork2.TextProvider;  //提供获取本地信息文本的功能
com.opensymphony.xwork2.LocaleProvider;//提供getLocale()方法来获取本地消息

  1)基本的数据验证

  • 要实现数据验证的功能,只需要在Action类中覆盖实现validate方法即可;在validate方法内部,对请求传递过来的数据进行校验,如果不满足要求,那么添加例外信息到父类用于存放例外的集合中。示例代码如下:

package cn.javass.hello.struts2impl.action;  

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
    private String account;
    private String password;
    private String submitFlag;
    public String execute() throws Exception {
        this.businessExecute();
        return "toWelcome";
    }
    public void validate(){
        if(account==null || account.trim().length()==0){
            this.addFieldError("account", "账号不可以为空");
        }
        if(password==null || password.trim().length()==0){
            this.addFieldError("password", "密码不可以为空");
        }
        if(password!=null && !"".equals(password.trim()) && password.trim().length()<6){
            this.addFieldError("password", "密码长度至少为6位");
        }
    }
    /**
     * 示例方法,表示可以执行业务逻辑处理的方法,
     */
    public void businessExecute(){
        System.out.println("用户输入的参数为==="+"account="+account+",password="+password+",submitFlag="+submitFlag);
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSubmitFlag() {
        return submitFlag;
    }
    public void setSubmitFlag(String submitFlag) {
        this.submitFlag = submitFlag;
    }  

}  

  从上面的示例可以看出,在validate方法中,可以对用户请求中传递过来的数据进行验证,同一个数据可以进行多方面的验证。

  如果验证结果是数据不正确,那么就使用父类提供的addFieldError方法来添加验证的错误消息。addFieldError方法有两个参数,前面的是消息的key值,后面是具体的消息。

  • 细心的你肯定发现了,validate方法是没有返回值的,那么当验证后,如果有数据没有通过验证,该返回到什么页面呢?这就需要在struts.xml中的Action配置里面,添加一个名称为input的result配置,也就是说,如果validate方法中,有数据没有通过验证,那么会自动跳转回到该action中名称为input的result所配置的页面。示例如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.devMode" value="true" />        <!-- 设置了程序的运行模式 -->
    <constant name="struts.locale" value="zh_CN"/>         <!-- 设置程序运行所使用的locale -->
    <constant name="struts.i18n.encoding" value="utf-8"/>  <!-- 设置程序运行时用的编码方式 -->
    <!-- 正确设置后面两个参数,就可以解决Struts2的中文问题了。 -->

    <package name="helloworld"  extends="struts-default">
        <action name="helloworldAction" class="cn.javass.hello.struts2impl.action.HelloWorldAction">
            <result name="toWelcome">/s2impl/welcome.jsp</result>
             <result name="input">/s2impl/login.jsp</result>
        </action>
    </package>  

</struts> 

  • 当输入信息不满足条件的时候,将错误信息显示在前台页面上,代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; utf-8">
<title>Insert title here</title>
<style type="text/css">
ul,li {
    list-style-type:none;
    margin:0px;
    float:left;
}
</style>
</head>
<body>  

<form action="/struts2Deepen2/helloworldAction.action" method="post">
    <input type="hidden" name="submitFlag" value="login"/>
    <div>
        <font color=red><s:fielderror fieldName="account"/></font>
        <br/>
          账号:<input type="text" name="account">
    </div>
    <div>
        <font color=red><s:fielderror fieldName="password"/></font>
        <br/>
            密码:<input type="password" name="password">
    </div>
    <input type="submit" value="提交">
</form>  

</body>
</html>  

  在JSP页面中利用<s:fielderror/>标签在相应的字段处输出错误信息。但是,在实际开发中,<s:fielderror/>它会输出全部的错误信息内容。而如果想选择性地输出指定错误信息。我们可以使用如下代码解决:

<!-- 方法一 -->
<s:fielderror>
  <s:param>username</s:param> <!--显示指定的 username字段的 错误消息-->
<s:fielderror/>

<!-- 方法二 -->
<s:fielderror fieldName="username"/> <!--显示指定的 username字段的 错误消息-->  

  • 通过这个示例,你会发现,validate方法会先于execute方法被执行,只有validate方法执行后,又没有发现验证错误的时候,才会运行execute方法,否则会自动跳转到你所配置的input所对应的页面。

  2)访问本地信息

  在上面的示例中,你会发现在validate方法中,添加验证错误消息的时候,是采用的硬编码方式,也就是直接写死的字符串,这是很不好的:

  ① 不容易修改,比如要改变消息的内容,还得重新修改和编译类;

  ② 不利于国际化,如果要把中文的信息变换成英文的呢,同样要重新修改和编译类。

  可以通过访问本地信息的方式,把这些错误消息放置到Action类外部的配置文件中,在Action类内部只需要按照这些消息的key值去获取消息即可。这样一来,当消息发生变化的时候,只需要修改这个消息的配置文件即可。

  • 先来建立消息的配置文件,在Action类的路径下建立一个同名的properties文件,也就是文件名为HelloWorldAction.properties,然后在里面按照key=value的格式,添加要使用的错误消息。示例如下:
k1=\u5E10\u53F7\u4E0D\u5141\u8BB8\u4E3A\u7A7A
k2=\u5BC6\u7801\u4E0D\u5141\u8BB8\u4E3A\u7A7A
k3=\u5BC6\u7801\u957F\u5EA6\u5FC5\u987B\u57286\u4F4D\u4EE5\u4E0A

  可能你会觉得很奇怪,这都是些什么呀?其实是把中文的消息转换成了相应的unicode编码,比如k1后面的value值,其实就是“帐号不允 许为空”的unicode编码。只有这样,在程序里面读取到这些值的时候才会正确显示中文。有很多工具可以把中文转换成unicode编码,比如,native2ascii工具就可以实现。

  • Action里面,就修改validate方法,原来是直接写的中文字符串,现在应该修改成从配置文件中获取信息了,示例如下:

 public void validate(){
        if(account==null || account.trim().length()==0){
            this.addFieldError("account", this.getText("k1"));
        }
        if(password==null || password.trim().length()==0){
            this.addFieldError("password", this.getText("k2"));
        }
        if(password!=null && !"".equals(password.trim()) && password.trim().length()<6){
            this.addFieldError("password", this.getText("k3"));
        }
    }  

时间: 2024-09-14 10:21:15

Struts2实现Preparable接口和【struts2】继承ActionSupport类的相关文章

框架-新手求大神看看Struts2的preparable接口问题。

问题描述 新手求大神看看Struts2的preparable接口问题. 跟着尚硅谷的框架整合学的,有一步实在觉得奇怪. 编辑这是前端jsp页面的一个链接. 我在action中加了id这个属性,按道理struts会将这个id值写到action的成员变量id中,并调用input方法,然后这个action实现了preparable接口,于是加上了 public void prepareInput() { System.out.println(id); if(id != null){ model = e

struts2 0-action继承ActionSupport后action不能访问特定的方法是为什么

问题描述 action继承ActionSupport后action不能访问特定的方法是为什么 表单的action为: <form action="login.action"></form> struts2.xml的配置为: <action name="login" class="loginAction" method="userLogin"> <result name="ok

httpurlconnection-HttpURLConnection向struts2发送File对象,struts2接收不到

问题描述 HttpURLConnection向struts2发送File对象,struts2接收不到 我需要提供一个给其他项目使用的文件上传的接口,使用HttpURLConnection向struts2发送File对象,struts2接收不到,寻求帮助 解决方案 action有提供set和get方法吗?

struts2.1.6升级到struts2.3.20之后,所有action请求出现404,

问题描述 struts2.1.6升级到struts2.3.20之后,所有action请求出现404, GET http://localhost:8080/member/campaign/manager/campaign!registerList.action [HTTP/1.1 404 Not Found 6ms] 解决方案 我现在也升级到2.3.20 发现包互相依赖,现在启动不了.不知道你现在弄好了吗,能否分享一下你的经验. 解决方案二: 我现在也升级到2.3.20 发现包互相依赖,现在启动不

java面向对象—抽象类、接口与多继承

有时候,我们可能想要构造一个很抽象的父类对象,它可能仅仅代表一个分类或抽象概念,它的实例没有任何意义,因此不希望它能被实例化.例如:有一个父类" 水果(Fruit)",它有几个子类"苹果(Apple)"."橘子(Orange)"."香蕉(Banana)"等.水果在这里仅仅只是作为一个分类,显然水果的实例没有什么意义(就好像一个人如果告诉你他买了一些水果但是却不告诉你是苹果还是橘子,你很难想象他到底买的是什么.).而水果类又要能

name-spring3 struts2框架整合错误,提示说action类注入错误

问题描述 spring3 struts2框架整合错误,提示说action类注入错误 No bean named 'userService' is definedError creating bean with name 'action.UserAction': Injection of resource methods failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionExcepti

class-一个类可以只能继承一个抽象类,为什么接口可以多继承接口

问题描述 一个类可以只能继承一个抽象类,为什么接口可以多继承接口 一个类可以只能继承一个抽象类,为什么接口可以多继承接口.谢谢大神帮我回答 解决方案 接口抽象类继承接口与抽象类的继承黑马程序员--继承.抽象类.接口 解决方案二: 这是java中继承父类和实现接口的差别,是参照与C的继承关系规定的. 解决方案三: 类也可以继承多个类啊,只是不说抽象类而已! 解决方案四: 注意:类对接口的implements称作实现 不能叫做继承 . 当然 接口可以多继承接口 因为接口只定义行为 并不包含类别的含义

关于struts2.1.6升级到struts2.1.8的问题

问题描述 关于struts2.1.6升级到struts2.1.8的问题 最近因为struts2.1.6有bug 所有升级到了strtus2.1.8 但是升级了之后 就访问不了.action 升级过程中 我只更换了jar包和把web.xml里面的过滤器改了一下 其他的没有动了 我想知道有人和我一样碰到过这种问题吗 然后 是怎么样解决的 解决方案 Struts2.1.6中文乱码问题Struts 2.1.6 中文乱码问题struts2.1.6升级到struts2.3.15.1

对于Java中的接口实现多继承的疑问

问题描述 目前的理解接口:Interface   的作用就是包含一些抽象方法   然后再其他类中implement接口并override这些抽象方法        感觉纯粹只为了达到统一的方法名访问而作这么个抽象方法,跟直接在类中创建这么一个方法没啥区别      如果要做到像extend那样不重写方法就能使用父类的方法,Interface还是不行啊   实现的多继承也就变成了重写多个接口中的抽象方法,没有那层继承的意义啊 解决方案 嘿嘿,看看大师们是怎么用interface的.多看看设计模式,