zoukankan      html  css  js  c++  java
  • j2ee开发之struts2框架学习笔记

    Struts2框架技术重点笔记

    1.Struts2 是在webwork基础上发展而来。

    2.Struts2 不依赖struts APIservlet API

    3.Struts2提供了拦截器,表现层技术:jsp +freeMarket+ velocity

    4.Struts2可以对指定的方法进行校验,提供了全局范围,包范围和action范围的国际化资源文件的管理实现。

    环境搭建:找到对应的jar

    编写struts的配置文件

    <?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.action.extension" value="do" />

        <constant name="struts.devMode" value="false" />

        <constant name="struts.enable.DynamicMethodInvocation" value="false" />

        <package name="test" extends="struts-default">

          <action name="hello" class="test.hello">

          <result>/index.jsp</result>

          </action>

        </package>  

    </struts>

    web.xml中加入strutsMVC框架的启动配置。

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>

        <display-name>Struts 2 Mailreader</display-name>

        <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>

        <!-- Application Listener for Mailreader database -->

        <welcome-file-list>

            <welcome-file>index.html</welcome-file>

        </welcome-file-list>

    </web-app>

    逻辑处理类hello.java

    package test;

    import com.opensymphony.xwork2.ActionSupport;

    @SuppressWarnings("serial")

    public class hello extends ActionSupport{

    public static String MESSAGE="hello world!";

        public String execute() throws Exception{

         setMessage(MESSAGE);

         return SUCCESS;

        }

        

        private String message;

        public void setMessage(String message){

         this.message=message;

        }

        public String getMessage(){

         return message;

        }

    }

    前台jsp页面:

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>

    <%@ taglib prefix="s" uri="/struts-tags" %>

    <%

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    %>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

      <head>

        <base href="<%=basePath%>">

        <title>My JSP 'index.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

    <meta http-equiv="expires" content="0">    

    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

    <meta http-equiv="description" content="This is my page">

    <!--

    <link rel="stylesheet" type="text/css" href="styles.css">

    -->

      </head>

      <body>

        <h2>

        <s:property value="message"/>

        </h2>

      </body>

    </html>

    5.Struts2中的执行流程

    StrutsPrepareAndExecuteFilter   //struts2内部核心的类

    Interceptor,struts2 //内置的一些拦截器或者用户自己定义的拦截器

    Action               //用户自己编写的action,其中的action是线程安全的

    Result               //类似于forward请求转发

    Jsp/html             //视图层

    6.Struts2中指定多个配置文件

    <struts>

    <include file=”struts-user.xml”/>

    <include file=”struts-order.xml”/>

    </struts>

    7.Struts2有两种类型转换器

    局部转换器:

    针对某个action HelloWorldAction-conversion.properties,针对HelloWorldAction

    属性文件中,属性名=类型转换器的所在包+类名

    全局转化器:

    针对整个项目的action

    Xwork-conversion.properties

    例如:

    java.util.Date=ConvertDemo.DateTypeConverter

    重写方法:

    package ConvertDemo;

    import java.sql.Date;

    import java.text.SimpleDateFormat;

    import java.util.Map;

    import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

    //自己定义了类型转换器

    //如果对于局部类型转换器,则需要将某个属性文件对应于action

    public class DateTypeConverter extends DefaultTypeConverter{

        //重写方法

    @Override

    public Object convertValue(Map<String, Object> context, Object value,Class toType) {

    // TODO Auto-generated method stub

    SimpleDateFormat dateFormat =  new SimpleDateFormat("yyyyMMdd");

    try{

    if(Date.class==toType){//当字符串向date类型转换时

    //将value转换为string数组

    String params[] = (String [])value;

    //用dateFormat去按照索引解析字符串

    return dateFormat.parse(params[0]);

    }else if(toType==String.class) {//当data转换为字符串时

    Date date = (Date)value;

    //用dateFormat去解析字date

    return dateFormat.format(date);

    }    

    }catch(Exception e){

    e.printStackTrace();

    }

    return null;

    }  

    }

    7. 各个属性的理解:

     1.package:是来管理一组功能相关的action

     2.mytest:名字自己定义,主要是供继承所使用

     3.namespace:命名空间,作为访问action的路径的一部分

     4.extends:继承,struts-default包含了很多struts2定义的很多核心功能,拦截器等

    5.userActionaction的名称,来自于test.userAction

    6./success.jsp:返回的结果,导向一个页面

    7.注意:action的搜索顺序,为先在当前命名空间中查找,查找不到就返回上一级,知道追溯到默认的命名空间,即namespace为空字符串

    8.如何在配置文件中设置一些常见的常量?

    设置action的访问后缀

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

    设置开启动态方法调用

    <constantname=”struts.enable.DynamicMethodInvocation”value=”false”>

    设置文件的上传大小

    <constant name=”struts.multipart.maxSize” value=”1000000”>

    9.定义全局的视图,可以被其他的包所继承

    <package name="BasePackage" extends="struts-default">

    <global-results>

    <resultname="message">/WEB-INF/client/success.jsp</result>

    </global-results>

    </package>

    只要action返回一个message就会调转到success.jsp

    其他包的extends属性为extends=”BasePackage”

    10.action中几个默认值

    1.如果没有为action指定类class,默认是实现类ActionSupport

    2.如果没有为action指定要执行哪个方法,默认执行execute方法,该方法会返回一个String类型的success

    3.如果没有指定resultname,默认返回success

    11.在一个action中处理请求时将页面重定向到另外一个action?

    <action name="redirectAction">

    <result type="redirectAction">

    !-- action名称 -->

    <param name="actionName">s1</param>

    <!-- 命名空间名字 -->

    <param name="namespace">/school</param>

    </result>

    </action>

    注意将resulttype类型设置为redirectAction

    通过<param>设置要重定向到的action名称和所在的命名空间

    12.使得一个action将页面的内容原样输出

    <action name="plainText">

    <!-- 注意在这里,result的name为默认值success,不可以乱写 ,result类型一定为plainText-->

    <result type="plainText">

    <param name="location">/index.jsp</param>

    <!-- 指定读取文件的编码为utf-8 -->

    <param name="charSet">UTF-8</param>

    </result>

    </action>

    13.使用通配符进行action的动态方法调用

    <action name="hwa*" class="test.HelloWorldAction" method="{1}">

    <result name="success">/WEB-INF/client/message.jsp</result>

    </action>

    hwaAdd将执行action中的add方法

    hwaUpdate将执行action中的update方法。

    14.action获取请求参数

    视图层:

     <form action="<%=request.getContextPath()%>/test3/requestPara.do" method="post">

        id:<input type="text" name="person.id"><br>

        name:<input type="text" name="person.name"><br>

        <input type="submit" value="OK"/>

    </form>

    配置器:

    <!-- 测试请求参数 -->

    <action name="requestPara" class="test.RequestAction" method="execute">

    <result name="success">/WEB-INF/client/message.jsp</result>

    </action>

    Action:

    package test;

    import java.util.Date;

    import JavaBean.Person;

    public class RequestAction {

    private Person person;

    public Person getPerson() {

    return person;

    }

    public void setPerson(Person person) {

    this.person = person;

    }

    public  String addUI(){

    return "success";

    }

    public String execute(){

    return "success";

    }

    }

    结果显示层,通过el表达式输出对象的值:

     <!-- 访问RequestAction中的JavaBean对象中的数据 ,person是一个复合类型-->

        id=${person.id}<br/>

        name=${person.name}

    15.action进行输入校验

    <!-- 验证输入校验的action -->

    <package name="person" namespace="/person" extends="struts-default">

    <action name="manage_*" class="validate.PersonAction" method="{1}">

    <result name="input">/validate.jsp</result>

    <result name="message">/WEB-INF/page/message.jsp</result>

    </action>

    </package>

    action中利用代码实现合法性检查:

    package validate;

    import java.util.regex.Pattern;

    import com.opensymphony.xwork2.ActionContext;

    import com.opensymphony.xwork2.ActionSupport;

     

    /*

     * PersonAction测试了action的输入校验

     * 1.一定要继承ActionSupport

     * 2.并且重写validate方法

     * 3.将错误信息写入FieldError

     * 前台:

     * 1.要引入struts2的标签库<%@ taglib uri="/struts-tags"  prefix="s"%>

     * 2.导入显示标签:<s:fielderror/>

     * */

    public class PersonAction extends ActionSupport {

    // 注意:重写验证的方法,该方法对action中的所有方法进行校验,加@override注解

    //如果是对某个方法进行校验,就执行validateXxx方法,不再有@override注解

    //如果有错误信息或者类型转换失败,就会进入input视图,定义的返回为input的值在action中进行定向到validate.jsp页面

    public void validateUpdate() {

    if (this.username == null || "".equals(this.username.trim())) {

    // 向FieldError中添加错误信息

    this.addFieldError("username", "用户名不可以为空");

    }

    if (this.tel == null || "".equals(this.tel.trim())) {

    this.addFieldError("tel", "手机号不可以为空");

    } else {

    // 利用正则表达式检验

    if (!Pattern.compile("^1[358]\d{9}$").matcher(this.tel).matches()) {

    this.addFieldError("tel", "手机号格式不对");

    }

    }

    }

     

    public String getUsername() {

    return username;

    }

     

    public void setUsername(String username) {

    this.username = username;

    }

     

    public String getTel() {

    return tel;

    }

     

    public void setTel(String tel) {

    this.tel = tel;

    }

     

    // 定义用户名

    private String username;

    // 定义用户的电话

    private String tel;

     

    public String update() {

    ActionContext.getContext().put("message", "update successfully");

    return "message";

    }

     

    public String save() {

    ActionContext.getContext().put("message", "save successfully");

    return "message";

    }

    }

     

    如果是用配置文件检查:

    配置文件:

    <?xml version="1.0" encoding="utf-8"?>

    <!-- 指定校验配置文件的DTD信息 -->

     <!DOCTYPE validators PUBLIC

      "-//Apache Struts//XWork Validator 1.0.3//EN" 

     "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

    <!-- 校验文件的根元素 --> 

    <!-- 基于xml方法对action进行校验    xml文件和action放在同一个包下,如果对action中所有的方法进行校验,action名字-validation.xml -->

    <!-- 如果对于action中某个方法进行校验,就取名PersonAction-manage_save-validation.xml

         manage_*在struts配置文件中用了通配符

     -->

    <validators>

        <field name="username">

            <field-validator type="requiredstring">

                <param name="trim">true</param>

                <message>用户名不能为空!</message>

            </field-validator>

        </field>

        <field name="mobile">

            <field-validator type="requiredstring">

                <message>手机号不能为空!</message>

            </field-validator>

            <field-validator type="regex">

         <param name="expression"><![CDATA[^1[358]d{9}$]]></param>

         <message>手机号格式不正确!</message>

    </field-validator>

        </field>

    </validators>

    16.通过action访问几个作用域?

    action中的execute方法:

    public String execute(){

    ActionContext ctx = ActionContext.getContext();

    ctx.getApplication().put("application", "application");

    ctx.getSession().put("session","session");

    ctx.put("request", "request");

    return "message";

    }

    先取得一个上下文对象,在该对象中放入键值对,返回message;

    前台取值,    

    ${applicationScope.application}

    ${sessionScope.session}

    ${resuestScope.request}

    17.文件上传

    处理文件上传的action,

    public class FileUploadAction {

       //定义文件对象

    private File image;

       //定义问价名

    private String imageFileName;

    public  String getImageFileName() {

    return imageFileName;

    }

    public void setImageFileName(String imageFileName) {

    this.imageFileName = imageFileName;

    }

    public File getImage() {

    return image;

    }

    public void setImage(File image) {

    this.image = image;

    }

    //execute方法

    public String execute() throws IOException{

    //得到文件的上传路径,没有就创建

    String realPath = ServletActionContext.getServletContext().getRealPath("/images");

    System.out.println(realPath);

    //如果文件不为空,根据文件的真实路径和文件名创建文件保存路径 

        if(image!=null){

            File savefile = new File(new File(realPath),imageFileName);

            if(!(savefile.getParentFile().exists())){

             savefile.getParentFile().mkdirs();

            }

    //将该文件拷贝到该新创建的保存路径

         FileUtils.copyFile(image, savefile);

    //在上下文对象中放入一个标志message

         ActionContext.getContext().put("message", "ok");

        }

    return "success";

    }//end of execute

    处理多文件上传:

    public String execute2() throws IOException{

    String realPath = ServletActionContext.getServletContext().getRealPath("/images");

        System.out.println(realPath);   

        if(image!=null){

            File savedir = new File(realPath);

            if(!savedir.exists()){

             savedir.mkdirs();

            }

            for(int i=0;i<image.length;i++){

             File savefile=new File(savedir,imageFileName[i]);

             FileUtils.copyDirectory(image[i], savefile);

            }

        }

            ActionContext.getContext().put("message", "ok");

    return "success";

    }//end of execute

    imageimageFileName属性全部定义成数组处理

    struts中配置:

    <!--测试文件上传  -->

    <actionname="fileadd"class="FileUpload.FileUploadAction"method="execute">

    <resultname="success">/WEB-INF/client/uploadResult.jsp</resul>

    </action>

    uploadResult.jsp页面输出${message},判断是否成功上传

    18.action中如何申明拦截器?

    Struts.Xml中的配置:

    <packagename="test4"namespace="/test4"extends="struts-default>

    <!-- 注册拦截器 -->

    <interceptors>

    <!-- 声明自己的拦截器 -->

    <interceptorname="permission"class="Intercepter.PermissionInterceptor"></interceptor>

    <!--将该拦截器放入拦截器栈中-->

    <interceptor-stack name="permissionStack">

    <!-- 应用系统默认的拦截器栈 -->

    <interceptor-ref name="defaultStack"/>

    <!-- 加入自己的拦截器 -->

    <interceptor-ref name="permission"/>

    </interceptor-stack>

    </interceptors>

    <!-- 定义该action的全局视图 -->

    <global-results>

    <result name="success">/WEB-INF/client/IntercepterResult.jsp</result>

    </global-results>

    <action name="intercepter" class="Intercepter.IntercepterAction"

    method="execute">

    <!-- 调用拦截器时,要去调用新的拦截器栈permissionStack -->

    <interceptor-ref name="permissionStack"></interceptor-ref>

    </action>

    </package>

    PermissionInterceptor一定要去实现Interceptor接口,例如定义的一个许可拦截器,先判断session中是否有该用户,有的话,,,,没有的话,,,。

    public class PermissionInterceptor 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 invocation) throws Exception {

    // TODO Auto-generated method stub

    Object user = ActionContext.getContext().getSession().get("user");

    if (user != null) {

    return invocation.invoke();

    }

    ActionContext.getContext().put("message", "no permission");

    return "success";

    }

    }

    IntercepterResult.jsp页面中:

    ${message},如果sesssion中得不到user,提示:no permission

    19.struts中定义国际化文件?

    配置文件:

    <struts>

    <!--通过常量,将test定义为全局范围的资源文价 -->

    <constant name="struts.custom.i18n.resources" value="test"></constant>

    <package name="person" namespace="/person" extends="struts-default">

    <action name="manage" class="nativeDemo.managePersonAction">

    <result name="message">/WEB-INF/page/message.jsp</result>

    </action>

    </package></struts>

    1)在项目根路径下定义国际化文件:

    定义中文,test_zh_CN.properties,test为基础名,随便起

    定义英文,test_en_US.properties,test基础名,随便起

    {0}{1}是占位符

    2)定义包下的国际化文件:

    package_zh_CN.properties,package是必须写的

    3)定义针对于某个action的国际化文件:

    managePersonAction_zh_CN.properties,managePersonAction为action的名字

    搜素顺序:

    Action->包->项目根路径

    访问该国际化文件:

    对于Action:

    package nativeDemo;

    import com.opensymphony.xwork2.ActionContext;

    import com.opensymphony.xwork2.ActionSupport;

    /*

     * 在action中取值this.getText("name的值");

     *

     * */

    public class managePersonAction extends ActionSupport {

     

    @Override

    public String execute() throws Exception {

    //将国际化信息放入map集合中,key为message,值为我们定义的国际化信息的name

    //没有占位符的情况:

    //ActionContext.getContext().put("message",this.getText("welcome"));

            //有占位符的情况,参数多个一个String类型的数组:

    ActionContext.getContext().put("message",this.getText("welcome",new String[]{"admin","study"}));

    return "message";

    }

    }

     

     

     

    对于jsp:

    <body>

         <!-- 1.如果访问项目根路径,全局范围内的国际化文件,name为基础名test

              2.如果访问某个包下的国际化文件,包名/package

              3.如果访问包下的action,包名/actionName

              4.s:param标签是给参数占位的

              5.s:i18n控制优先访问的国际化文件的位置

          -->

    <s:i18n name="nativeDemo/managePersonAction">

    <s:text name="welcome">

    <s:param>jiaqing</s:param>

    <s:param>direct-visit</s:param>

    </s:text>

    </s:i18n>

    </body>

    20.采用EL表达式仅能访问valueStack中某个对象的属性。可以直接访问action中的属性

    21.struts2常用几个标签

    <!-- property标签 -->

    <s:set name="username" value="'admin'"></s:set>

    <s:property value="#username"></s:property>

    <br>

    <!-- iterator标签 -->

    <s:set name="mylist" value="{'xjq','mm','admin','teacher'}"></s:set>

    <s:iterator value="#mylist">

    <s:property></s:property>

    </s:iterator>

    <br>

    <!-- ifelse标签 -->

    <s:set name="age" value="210"></s:set>

    <s:if test="#age==23">

       23

    </s:if>

    <s:elseif test="#age==21">

       21

    </s:elseif>

     <s:else>

      not equal

     </s:else>

    <br>

    <!-- checkboxlist复选框 -->

    <s:checkboxlistname="list"list="{'java','net','C','php','javascript'}" value="{'java','net'}"></s:checkboxlist>

    <br>

    <!-- 如果为map集合 -->

    <s:checkboxlist name="map"list="#{1:'java',2:'net',3:'c#'}" listKey=key listValue=value value="{1}">

    </s:checkboxlist>

    如果list中放入一个bean对象,如何生成复选框?

    单选按钮:

    <s:radio name="map" list="#{1:'java',2:'.net',3:'c#'}" listKey="key" listValue="value" value="{3}">

    </s:radio>

    下拉列表:

    <s:select name="map" list="#{1:'java',2:'.net',3:'c#'}" listKey="key" listValue="value" value="{1}" >

    </s:select>

    22.防止表单重复提交

    配置的struts.xml

    <package name="itcast" namespace="/mytest" extends="struts-default">

    <action name="handle" class="test.BdAction">

    <interceptor-ref name="defaultStack"/>

    <interceptor-ref name="token"/>

    <result name="invalid.token">/tags.jsp</result>

    <result name="success">/WEB-INF/page/message.jsp</result>

    </action>

    </package>

    视图层的表单:

    <s:form action="handle" namespace="/mytest" method="post">

    name:<s:textfield name="name"></s:textfield><s:token></s:token>

      <input type="submit" value="发送" />

    </s:form>

    带着热忱学技术,带着耐心做技术,带着分享去交流,带着微笑探我们的程序人生!
  • 相关阅读:
    Atlassian JIRA 系统服务部署(包括5.0.3版本和7.2版本)
    LoadRunner系列之—-01 接口压力测试脚本
    oracle 正则查询json返回报文中某个字段的值
    Selenium系列之--05 页面元素找不到的分析思路
    Selenium系列之--04 不同浏览器获取Xpath的方法
    Selenium系列之--01开篇
    【问题记录】LoadRunner 接口压测-json格式报文
    oracle随机数
    十 删除topic中的数据
    九 assign和subscribe
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/5677226.html
Copyright © 2011-2022 走看看