Struts2原创学习笔记

创建Action类
1、简单的POJO
2、实现接口com.opensymphony.xwork2.Action
3、继承com.opensymphony.xwork2.ActionSupport类
第三种为常用方式:提供了获取国际化信息的方法、数据校验的方法、默认用户请求的execute方法,同时还增加了对验证、本地化等的支持。
还提供了5个字符串类型的静态常量
SUCCESS 正常
NONE 正常,但不返回任何提示
ERROR 错误
INPUT 用户需要更多的输入才能顺利执行
LOGIN 登陆后才可以


访问Servlet API对象
三种方式:
一、使用ActionContext类获取ServletAPI对象对应的MAP对象
ActionContext context=ActionContext.getContext();
Map<String,Object> session=context.getSession();
//session访问
session.put("k", "我是session");
Map request = (Map) context.get("request");
//request访问
request.put("k", "我是request");
Map<String,Object> application=context.getApplication();
//application访问
application.put("k", "我是application");


二、使用ServletActionContext类直接获取原生对象
HttpServletRequest req=ServletActionContext.getRequest();
HttpServletResponse res=ServletActionContext.getResponse();
HttpSession ses=ServletActionContext.getRequest().getSession();


三、通过实现接口,向Action注入相应的对象(文件夹外有该类,直接可调用)
RequestAware 注入了HttpServletRequest对象对应的Map对象
SessionAware 注入了HttpSession对象对应的Map对象
ApplicationAware 注入了ServletContext对象对应的Map对象
ServletContextAware 注入了ServletContext对象
ServletRequestAware 注入了ServletRequest对象
ServletResponseAware 注入了ServletResponse对象


Struts2
constant常量配置:
<!-- 把它设置为开发模式,发布时要设置为false -->
    <constant name="struts.devMode" value="true" />
    <!-- 设置在class被修改时是否热加载,发布时要设置为false -->
    <constant name="struts.convention.classes.reload" value="true"/>
    <!-- 自动动态方法的调用,使用这个设置后可以这样调用:action!method -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <!-- 指定jsp文件所在的目录地址 -->
    <constant name="struts.convention.result.path" value="/WEB-INF/content/" />
    <!-- 使用struts-default默认的转换器,如果是rest的使用:rest-default,rest需要rest的jar插件 -->
    <constant name="struts.convention.default.parent.package" value="struts-default"/>
    <!-- 用于配置包名后缀。默认为action、actions、struts-->
    <constant name="struts.convention.package.locators" value="actions" />
    <!-- 用于配置类名后缀,默认为Action,设置后,Struts2只会去找这种后缀名的类做映射 -->
    <constant name="struts.convention.action.suffix" value="Action"/>
    <!-- 设置即使没有@Action注释,依然创建Action映射。默认值是false。因为Convention-Plugin是约定优于配置的风格,
        可以不通过注解根据预先的定义就能访问相应Action中的方法 -->
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <!-- 自定义jsp文件命名的分隔符 -->
    <constant name="struts.convention.action.name.separator" value="-" />
    <!-- 国际化资源文件名称 -->
    <constant name="struts.custom.i18n.resources" value="i18n" />
    <!-- 是否自动加载国际化资源文件  -->
    <constant name="struts.i18n.reload" value="true" />
    <!-- 浏览器是否缓存静态内容 -->
    <constant name="struts.serve.static.browserCache" value="false" />
     <!-- 上传文件大小限制设置 -->
    <constant name="struts.multipart.maxSize" value="-1" />
    <!-- 主题,将值设置为simple,即不使用UI模板。这将不会生成额外的html标签 -->
    <constant name="struts.ui.theme" value="simple" />
    <!-- 编码格式 -->
    <constant name="struts.i18n.encoding" value="UTF-8" />


package配置:必须指定name属性,extends可选择继承Struts2的默认包struts-default
也可以继承其他已有的包,子包可以继承多个父包中的拦截器、拦截器栈、action配置
<package name="my" namespace="/" extends="struts-default" >
namespace设置命名,默认为"",这里设置的是根命名
<global-results>
            <result name="success">login.jsp</result>
        </global-results>
这里配置的是全局视图,对所有的action都有效(同名情况下局部视图优先)
    <action name="nle" class="cn.Anle" method="ks">
同一个命名空间不能有相同name的action
如果不设置class,将会使用系统默认的ActionSupport类(显然,这里调用的是cn.Anle.ks方法)
        <result name="success">/1.jsp</result>
返回的视图,name默认值是success,type默认值是dispatcher(转发跳至物理视图)
dispatcher org.apache.struts2.dispatcher.ServletDispatcherResult 默认结果类型,用来呈现JSP页面
chain com.opensymphony.xwork2.ActionChainResult 将action和另外一个action链接起来
freemarker org.apache.struts2.views.freemarker.FreemarkerResult 呈现Freemarker模板
httpheader org.apache.struts2.dispatcher.HttpHeaderResult 返回一个已配置好的HTTP头信息响应
redirect org.apache.struts2.dispatcher.ServletRedirectResult 将用户重定向到一个已配置好的URL
redirectAction org.apache.struts2.dispatcher.ServletActionRedirectResult 将用户重定向到一个已定义好的action
stream org.apache.struts2.dispatcher.StreamResult 将原始数据作为流传递回浏览器端,该结果类型对下载的内容和图片非常有用
velocity org.apache.struts2.dispatcher.VelocityResult 呈现Velocity模板
xslt org.apache.struts2.views.xslt.XSLTResult 呈现XML到浏览器,该XML可以通过XSL模板进行转换
plaintext org.apache.struts2.dispatcher.PlainTextResult 返回普通文本类容
    </action>
</package>


Struts2包含配置:
在package外,加入include标签;
<struts>
<include file="struts1.xml"></include>
<include file="struts2.xml"></include>
</struts>  




动态配置调用方法:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="my" namespace="/" extends="struts-default" >
        <action name="pojo" class="cn.Anle">
            <result name="success">/1.jsp</result>
        </action>
    </package>
</struts>  
这时,函数拥有了多个方法,可调用pojo!《方法名》访问不同的方法,大大的减少了action的个数。
但不推荐,存在安全隐患,将URL暴露在外。
可通过标签关闭动态访问:
<constant name="struts.enable.DynamicMethodInvocation" value="false" />


当然,还有一种通配符法:
<action name="*_*" class="www.whprototype.com.{1}" method="{2}">
或者单个方法通配
<action name="*Action" class="www.whprototype.com.Hellowaction" method="{1}">


action的这三个属性都支持通配符调用,乃至result中跳转地址也可以用通配符跳转


拦截器
配置:<interceptor name="拦截器名称" class="拦截器实现类">
拦截器栈配置:
    <interceptors>
        <interceptor name="" class=""></interceptor> //拦截器
        <interceptor-stack name=""> //栈名称
            <interceptor-ref name=""></interceptor-ref>        //拦截器名称
        </interceptor-stack>
    </interceptors>


使用的时候:
<action name="nle" class="cn.Anle" method="ks">
            <result name="success">/1.jsp</result>
            <interceptor-ref name="defaultStack"/> //默认的框架拦截器
            <interceptor-ref name="拦截器名称||栈名称" />
</action>


定义拦截器类(也可以继承AbstractInterceptor类,无需初始化和销毁)
public class com implements Interceptor{


@Override
public void destroy() {
// TODO Auto-generated method stub
//销毁方法
}


@Override
public void init() {
// TODO Auto-generated method stub
//初始化
}


@Override
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
//拦截动作
arg0.invoke();成功跳转
return null;
}


}


上传和下载(Common-FileUpload框架+Common-io):
表单的enctype属性:
application/x-www-form-urlencoded //默认的表单提取数据
multipart/form-data //会以二进制流的方式处理表单数据(上传)
text/plain //适合通过表单发送邮件,action为mailto:URL


上传类继承ActionSupport后,给予正常的命名getter和setter方法,可自动获取其类型,文件名称。
命名正确,框架自动给予:
File  file //文件框的name
String fileContentType //文件的类型(name+ContentType)类型大全见笔者另一个笔记
String fileFileName //文件的名称(name+FileName)


复制文件调用commons-io-2.0.1.jar中的方法:
FileUtils.copyFile(file,newFile("相对路径"+fileFileName));


上传限制大小(maximumSize)和类型(allowedTypes),可在Struts中action中加入以下内容:
<interceptor-ref name="fileUpload" >
                <param name="allowedTypes">
                    image/png,image/gif,image/jpeg //上传类型,','隔开
                </param>
                <param name="maximumSize">1048576</param> //最大上传大小,默认2M
            </interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> //默认框架
不符合会跳至input视图


多文件上传时仅仅需要加个[],利用for循环即可。


下载:
<action name="xz">
<param name="inputPath">/upload</param>
        <result name="succsee" type="stream"> //类型为stream
                <param name="contentType">application/octet-stream</param> //下载文件类型
                <param name="inputName">inputStream</param> //指定下载入口输入流
                <param name="contentDisposition">attachment;filename="${fileName}"</param>
//附件的形式;文件名称为下载显示的名称
                <param name="bufferSize">4096</param>
//下载时缓冲的大小
        </result>
</action>


java文件处理:
继承ActionSupport,实现上述getter和setter方法(inputPath下载目录、filename下载文件名称)
inputStream文件输入流,
private InputSteram InputStream;
public InputStream getInputStream() throws FileNotFoundException{
String path=ServletActionContext.getServletContext().getRealPath(inputPath);
return new BufferedInputStream(new FileInputStream(path+"\\"+getFileName()));
}


public String execute(){
return SUCCESS;
}


<a href="xz?fileName=ss.jpg">下载</a>


OGNL(后进先出)
<%@taglib prefix="s" uri="/struts-tags" %>//导入内库
将表单或Struts2标签与特定的JAVA数据绑定起来,用于将数据移入移出框架(直接值栈中获取数据,无需存session或request)
数据类型转换,数据进入和流出框架,在页面数据的字符串类型和java数据类型之间转换(转换失败会进入input视图)


例:
<s:form action="ac" namespace="/" method="post"> //提交内容,若数据类型不对,将会提示至<s:fielderror />
    <s:textfield name="name" label="账号"></s:textfield>
    <s:password name="pass" label="密码"></s:password>
    <s:submit value="提交"></s:submit>
</s:form>


<s:property value="name"/>
<s:property value="pass"/> //从数据栈中直接获取数据




定义类型转换器(鸡肋):
第一步(定义转换类):
public class DateC extends StrutsTypeConverter{


//数据移入时
@Override
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
/*[com.opensymphony.xwork2.ActionContext.locale, com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp, xwork.NullHandler.createNullObjects, conversion.property.fullName, report.conversion.errors, xwork.MethodAccessor.denyMethodExecution]
[zh_CN, false, true, timeDate, true, true]*/
//以上是arg0的数据、arg1是提交数据的总集合
return new Date();
}
//数据移出时
@Override
public String convertToString(Map arg0, Object arg1) {
// TODO Auto-generated method stub
return new SimpleDateFormat("yyyy年MM月dd日").format(arg1);
}


}
第二步(创建配置文件):
全局范围类型转换器:
xwork-conversion.properties
内容(转换类的全名=转换器类的全名):
java.util.Date=cn.DateC
特定类的类型转换器:
ClassName-conversion.properties
内容(特定类的属性名=转换器类的全名)


第三步:
action类写好getter setter方法.继承ActionSupport类


OGNL表达式:
#parameters.number等于request.getParameter("number");
#request.info等于request.getAttribute("info");
#session.info等于session.getAttribute("info");
#application.info等于application.getAttribute("info");
#attr.info 从小到大访问:PageContext、HttpServletRequest、HttpSession、ServletContext


例:
request;<s:property value="#request.info"/><br />
session;<s:property value="#session.info"/><br />
application;<s:property value="#application.info"/><br />
parameters;<s:property value="#parameters.number"/><br />
attr;<s:property value="#attr.info"/>从小到大访问:PageContext、HttpServletRequest、HttpSession、ServletContext<br />
size:<s:property value="book.size()"/><br />
  <!-- 把集合的对象放入集合的栈顶(丢失的快)先进后出-->
  <s:iterator value="book">
    <s:property value="name"/>,<s:property value="time"/>,<s:property value="bh"/>
  </s:iterator>
  <br />
  <!-- 不把集合的对象放入集合的栈顶(丢失的慢)-->
  <s:iterator value="book" var="b">
    <s:property value="#b.name"/>, <s:property value="#b.time"/>, <s:property value="#b.bh"/>
  </s:iterator>


<!-- 上下文参数直接用#号引用 -->
储存访问String[]、Map数据
  <s:set name="r" value='{"javaee","asp.net","JQuery"}'></s:set>
  <s:iterator value="#r">
    <s:property/>
  </s:iterator>
   <s:set name="rr" value='#{"c":"haha","asp.net":"xixi","JQuery":"wuwu"}'></s:set>
  <s:iterator value="#rr">
    <s:property value="key"/>
     <s:property value="value"/>
  </s:iterator>




<s:select name="name" list="book"(list数据) listKey="name"(value) listValue="bh"(显示的)>
  <s:submit value="提交" />
</s:select>
<s:radio>单选框同理
MAP生成单选按钮
 <s:radio name="sex" list='#{"1":"男","2":"女"}' listKey="key" listValue="value" />




Struts2验证框架:
@Override
public void validate() {
// TODO Auto-generated method stub
//验证框架
super.validate();
}
验证时,会先调用validate方法,如果不符合,则跳至input视图
super.addFieldError("参数", "原因");
如果不是execute方法,例如:XXX()方法,则重写该方法的validateXXX()方法


也可以利用配置文件:<ActionClassName>-validation.xml,且与该java文件同包
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC 
        "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
        "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
    <field name="name">
        <!-- 用户名非空验证 -->
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>请填写用户名</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="minLength">4</param>
            <param name="maxLength">6</param>
            <message></message>
        </field-validator>
    </field>
    <field name="telephone">
        <field-validator type="regex">
            <param name="expression">
                <![CDATA[(\d{9})]]>
            </param>
            <message>手机号码格式不正确</message>
        </field-validator>
    </field>
</validators>


如果其他方法调用的时候,需要<ActionClassName>-<ActionAliasName>-validate.xml
该方法复用性高,推荐第二种验证框架
其中type有:
required 必填验证器
requiredstring 必填字符串验证器
stringlength 字符串长度验证器
regex 表达式验证
email 邮箱验证器
int 整数验证器
double 双精度验证器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值