1. 上传文件

大部分项目避免不了要上传文件.

struts2提供了封闭的上传文件的入口, 网络上也存在大量的插件用于网页表单中上传文件.

由于自己习惯用SSH框架, 所以介绍一下struts2中文件上传的要点.

struts2对文件上传的格式,及上传文件的大小有很好的限制.

#Constants
#struts.locale=zh_CN
struts.i18n.encoding=UTF-8
struts.action.extension=,
struts.objectFactory=spring
struts.custom.i18n.resources=messages
#1G
struts.multipart.maxSize=1048576000
struts.ui.theme=css_xhtml
#struts.enable.SlashesInActionNames=true
struts.devMode=false
struts.i18n.reload=true
struts.configuration.xml.reload=true
struts.serve.static.browserCache=false
struts.ui.theme=simple

上传时的页面 DOM

<s:file cssClass="doc" name="documents[0].actionFile" />

这样上传的文件会自动map到对象的属性上, 或者我们使用File []fileArray来预存表单提交到action的文件队列.

不过通过此方法上传的文件队列是没有文件类型和文件名的,且在服务器以临时文件存在, 而且我们仍需要对等的使用 String []fileArrayFileName来存取对应的文件名.当然还有ContentType.

所以到了action阶段, 需要再对文件进行IO重写操作,以保证文件以正确的格式存在合适的地方.

以下代码用于读取存文件.

public static JSONObject handlerFileUpload(String dir, File file,
String fileName) throws IOException {
JSONObject jo = new JSONObject();
String realpath = ServletActionContext.getServletContext().getRealPath(
dir);//获取根目录+存放目录
System.out.println("realpath: " + realpath);
File doc;
if (file != null) {
doc = new File(realpath, fileName);//创建文件
if (!doc.exists()) {
if (!doc.getParentFile().exists()) {
doc.getParentFile().mkdirs();//判断目录
}
OutputStream os = new FileOutputStream(new File(realpath,
fileName));
InputStream is = new FileInputStream(file);
byte[] buf = new byte[1024];
int length = 0; while (-1 != (length = is.read(buf))) {
os.write(buf, 0, length);//写文件
}
is.close();
os.close();
}
jo.put("size", "" + file.length() / 1000 / 1000.0);//获取文件信息
jo.put("fileName", fileName);
jo.put("type", new MimetypesFileTypeMap().getContentType(file));
}
System.err.println("file:" + jo);
return jo;//返回文件信息Json
}

2. 上传图片

上传图片使用了最新的Ueditor的文件上传功能, Ueditor是个强大的富文本编辑器,可以编辑HTML或者纯文本, 且能带格式,字体,字号,表格,段落,附件,插图,link.

文件目录:

基本上把

WebContent/ueditor/jsp/lib

下的jar包考到项目的lib下, 就可以使用啦.

不过, 若需要配置上传的路径, 附件, 插图, 涂鸦, 文件, 视频的上传到指定路径则需要配置一个json文件: /WebContent/ueditor/jsp/config.json

/* 上传图片配置项 */
"imageActionName": "uploadimage", /* 执行上传图片的action名称 */
"imageFieldName": "upfile", /* 提交的图片表单名称 */
"imageMaxSize": 2048000, /* 上传大小限制,单位B */
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
"imageCompressEnable": true, /* 是否压缩图片,默认是true */
"imageCompressBorder": 1600, /* 图片压缩最长边限制 */
"imageInsertAlign": "none", /* 插入的图片浮动方式 */
"imageUrlPrefix": "", /* 图片访问路径前缀 */
"imagePathFormat": "/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
/* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
/* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
/* {time} 会替换成时间戳 */
/* {yyyy} 会替换成四位年份 */
/* {yy} 会替换成两位年份 */
/* {mm} 会替换成两位月份 */
/* {dd} 会替换成两位日期 */
/* {hh} 会替换成两位小时 */
/* {ii} 会替换成两位分钟 */
/* {ss} 会替换成两位秒 */
/* 非法字符 \ : * ? " < > | */
/* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */

需要注意的是根路径指向的是tomcat的webapps,并不是项目目录.

页面调用:

  1. 引用js包

    <script type="text/javascript" src="../ueditor/ueditor.config.js"></script>
    <script type="text/javascript" src="../ueditor/ueditor.all.js"></script>
    <script type="text/javascript" src="../ueditor/lang/en/en.js"></script>
    <script type="text/javascript" src="../resources/Admin/js/imageUploadModel.js"></script>
  2. 页面DOM
    <img id="preview" alt="The picture is missing or still not upload" src="" class="bannerimg" />
    <s:textfield id="picture" name="headerImg" onclick="upImage()" cssClass="scanimg input-sm" />
    <button type="button" class="input-sm" href="javascript:void(0);" onclick="clearImage();">Clear Image</button>
  3. JS实现
    var _editor = UE.getEditor('upload_ue');
    _editor.ready(function() {
    // 设置编辑器不可用
    // _editor.setDisabled(); 这个地方要注意 一定要屏蔽
    // 隐藏编辑器,因为不会用到这个编辑器实例,所以要隐藏
    _editor.hide(); // 侦听图片上传
    _editor.addListener('beforeinsertimage', function(t, arg) {
    // 将地址赋值给相应的input,只去第一张图片的路径
    var imgs = '';
    for ( var a in arg) {
    imgs += arg[a].src + ',';
    }
    imgs.toString().replace(/(,$)/g,'')
    $("#picture").attr("value", arg[0].src);
    // 图片预览
    $("#preview").attr("src", arg[0].src);
    }) });
    // 弹出图片上传的对话框
    function upImage() {
    var myImage = _editor.getDialog("insertimage");
    myImage.open();
    } //清除图片
    function clearImage() {
    $("#picture").attr("value", "");
    // 图片预览
    $("#preview").attr("src", "");
    } //预览图片功能
    $(".scanimg").hover(function() {
    $thisImg = $(this).prev("img");
    var imgObj = new Image();
    $widthU = $thisImg.css('width');
    $width = $widthU.substring(0, $widthU.indexOf('px'));
    $scanleft = $(this).position().left;
    $scantop = $(this).position().top;
    $thisImg.css({
    "left" : ($scanleft + $width * 1.4) + "px",
    "top" : ($scantop - $width / 3) + "px"
    });
    $thisImg.show();
    }, function() {
    $(this).prev("img").hide();
    });
  4. 预览css
    .scanimg {
    cursor: pointer;
    } .scanimg:HOVER {
    color: red;
    text-decoration: underline;
    } .bannerimg {
    display: none;
    position: absolute;
    width: 200px;
    min-height: 50px;
    background-color: rgba(66,139,202,1);
    /* min-width: 500px; */
    /* max-width: 600px; */
    }

至此, 所有相关的要素准备完毕.

预览样式:

3. validation

表单都需要验证,一般有三种方式来处理验证表单的问题

  1. jQuery validation.js来做

    $(document).ready(function() {
    $('#user').next().slideDown(0);
    validate();
    }); function validate() {
    var rules = {
    email : {
    required : true,
    email : true,
    uniquedEmail : true
    },
    username : {
    required : true,
    maxlength: 16
    },
    password : {
    required : true,
    rangelength : [ 8, 16 ]
    },
    company : {
    required : true,
    maxlength : 16
    }
    }
    formValidate.validate('myform', rules);
    } formValidate = {
    validate : function(formId, rules) {
    validateForm(formId, rules);
    }
    } function validateForm(formId, rules, message) {
    $('#' + formId)
    .validate(
    {
    debug : true, // 调试模式取消submit的默认提交功能
    errorClass : "error-msg", // 默认为错误的样式类为:error
    focusInvalid : false, // 当为false时,验证无效时,没有焦点响应
    onkeyup : false,
    submitHandler : function(form) { // 表单提交句柄,为一回调函数,带一个参数:form
    form.submit(); // 提交表单
    },
    rules : rules,
    messages : {
    password : {
    rangelength : 'The length of the password you input must be between 8 and 16 characters'
    },
    oldPwd : {
    rangelength : 'The length of the password you input must be between 8 and 16 characters'
    },
    newPwd : {
    rangelength : 'The length of the password you input must be between 8 and 16 characters'
    },
    confirmPwd : {
    rangelength : 'The length of the password you input must be between 8 and 16 characters'
    }
    }
    });
    } jQuery.validator.addMethod("tele", function(value, element) { var tel = /^\d{3,4}-?\d{7,9}$/; return this.optional(element) || (tel.test(value)); }, "Please write right tele number"); jQuery.validator.addMethod("uniquedEmail", function(value, element) {
    var dataJson = new Object();
    $.ajax({
    url : 'isRegEmailExist',
    type : 'post',
    data : {
    email : value
    },
    async : false, // 默认为true 异步
    error : function() {
    dataJson.status = 502;
    },
    success : function(data) {
    dataJson = JSON.parse(data); }
    });
    return this.optional(element) || (dataJson.status == 200);
    }, "The email is existed, please input other one!");
    <s:form action="reg" method="post" enctype="multipart/form-data" id="myform">
    .error-msg {
    color: #ff0000;
    }

    上述的方式在于灵活多变,不便的地方也看到了,需要调用ajax来请求服务器验证,且不同的浏览器对ajax返回的内容有不同的解释.                                                                                                   默认校验规则
    (1)required:true                必输字段
    (2)remote:"check.php"      使用ajax方法调用check.php验证输入值
    (3)email:true                    必须输入正确格式的电子邮件
    (4)url:true                        必须输入正确格式的网址
    (5)date:true                      必须输入正确格式的日期 日期校验ie6出错,慎用
    (6)dateISO:true                必须输入正确格式的日期(ISO),例如:2009-06-23,1998/01/22 只验证格式,不验证有效性
    (7)number:true                 必须输入合法的数字(负数,小数)
    (8)digits:true                    必须输入整数
    (9)creditcard:                   必须输入合法的信用卡号
    (10)equalTo:"#field"          输入值必须和#field相同
    (11)accept:                       输入拥有合法后缀名的字符串(上传文件的后缀)
    (12)maxlength:5               输入长度最多是5的字符串(汉字算一个字符)
    (13)minlength:10              输入长度最小是10的字符串(汉字算一个字符)
    (14)rangelength:[5,10]      输入长度必须介于 5 和 10 之间的字符串")(汉字算一个字符)
    (15)range:[5,10]               输入值必须介于 5 和 10 之间
    (16)max:5                        输入值不能大于5
    (17)min:10                       输入值不能小于10 

  2. 编码方式校验

       1) Action一定要继承自ActionSupport

         2) 针对某个要进行校验的请求处理方法编写一个 public void validateXxx()方法,在方法内部进行表单数据校验.

        3) 也可针对所有的请求处理方法编写public void validate()方法。

        4) 在校验方法中,可以通过addFieldError()方法来添加字段校验错误消息。

        5) 当校验失败时,Struts框架会自动跳转到name为input的Result页面。在校验失败页面中,可以使用<s:fielderror/>来显示错误消息

        6) 简单,灵活。但重用性不高。

  3. XML配置方式校验。在编码方式之前被执行。 

    1) 针对要校验的Action类,在同包下编写一个名为:Action类名-validation.xml校验规则文件。

    2) 在校验规则文件中添加校验规则:具体的校验器名,参数可参看Struts2的reference或Struts2的API。

    •   a) Field校验:针对Action类中每个非自定义类型的Field进行校验的规则。

    1.     <field name="要校验的Field名">
           <field-validator type="校验规则器名" short-circuit="是否要短路径校验(默认是false)">
               <param name="校验器要使用的参数名">值</param>
                  <message>校验失败时的提示消息</message>
        </field-validator>
        <!-- 还可添加其它的校验规则 -->
       </field>
       
           b) 非Field校验:针对Action类的某些Field使用OGNL表达进行组合校验。
          <validator type="fieldexpression">
        <param name="fieldName">pwd</param>
           <param name="fieldName">pwd2</param>
           <param name="expression"><![CDATA[pwd==pwd2]]></param><!-- OGNL表达式 -->
           <message>确认密码和密码输入不一致</message>
       </validator>
       
           c) visitor校验:主要是用来校验Action类中的自定义类型Field。(针对使用模型驱动方式时)
             i) 在Action类的的校验规则文件中针对自定义类型Field使用visitor校验规则。
          <!-- 针对自定义Field使用visitor校验 -->
       <field name="user">
        <field-validator type="required" short-circuit="true">
                  <message>用户的信息必填</message><!-- 消息前缀 -->
        </field-validator>
        <field-validator type="visitor"><!-- 指定为visitor校验规则 -->
         <param name="context">userContext</param><!-- 指定本visitor校验的上下文名 -->
                  <param name="appendPrefix">true</param><!-- 是否要添加校验失败消息的前缀 -->
                  <message>用户的</message><!-- 消息前缀 -->
        </field-validator>
       </field>
          ii) 针对visitor的Field编写一个校验规则文件.文件名为: visitor字段类型名[-visitor校验的上下文名]-validation.xml. 例如: 本例中的文件名为User-userContext-validation.xml
                        注意: 此文件要存放到visitor字段类型所在的包下.
          iii) 在visitor的Field校验规则文件中针对要校验的Field添加校验规则.
         3) 在校验失败页面(名为input的result页面)中,可以使用<s:fielderror/>来显示错误消息。
         4) 默认情况下,XML的校验规则对Action中所有的请求处理方法生效.此时应该只针对每个要校验的请求处理方法指定校验。有两种方式:
            i) 只为Action中的指定方法指定校验规则文件,配置文件命名为:Action类型名-别名-validation.xml,
                            别名是要校验的方法对应的Action标签的name属性值。
                            如:UserAction在struts2.xml的配置为:
          <package name="my" extends="struts-default" namespace="/">
        <action name="user_*" class="com.javacrazyer.web.action.UserAction" method="{1}">
         <result name="success">/info.jsp</result>
         <result name="input">/user_{1}.jsp</result>
        </action>
          </package>              
                      ● UserAction中有registe方法和login方法,要对registe方法进行校验,则它的校验规则文件名为:UserAction-user_registe-validation.xml。
                       ● 如果使用visitor校验器,必需指定visitor校验的上下文名。
            ii) 在校验拦截器中指定要验证的方法。不太实用。
         <action name="user_*" class="com.javacrazyer.web.action.UserAction" method="{1}">
          <result name="success">/info.jsp</result>
          <result name="input">/user_{1}.jsp</result>
           <interceptor-ref name="defaultStack">
              <!-- 给校验拦截器指定不进行校验的方法列表:用逗号隔开 -->
              <param name="validation.excludeMethods">*</param>
              <!-- 给校验拦截器指定要进行校验的方法列表:用逗号隔开 -->
              <param name="validation.includeMethods">regist</param>
            </interceptor-ref>
         </action>
         5) 同时使用客户端校验和服务器端校验
            i) 设置<s:form>标签的validate属性:
               false:默认值。校验框架只执行服务器端校验。
               true:先执行客户端校验,然后再执行服务器端校验。
               form标签会根据你在服务器端配置的验证规则生成对应的JavaScript验证代码。
                            目前支持的内置校验器:required、requiredstring、stringlength、regex validator、email、url、int、double
            ii) 不太好用,不建议使用。建议使用jQuery进行页面表单校验。
         6) 自定义校验器:
            i) 继承自FieldValidatorSupport抽象类。重写validate(Object obj)方法
            ii) 注册校验器类. 在应用程序的classpath下新建一校验器注册文件。名为validators.xml,内容如下:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE validators PUBLIC
              "-//OpenSymphony Group//XWork Validator Config 1.0//EN"
              "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
      <validators>
        <validator name="校验器名" class="校验器类的全限定名"/> 
      </validators>
       

   4. Annotation方式校验: Struts2提供了注解的方式校验

    1.   1) @Validation 指明这个类或者接口将使用基于注解的校验。Struts2.1中已被标识为过时。
        2) @Validations() 在同一个方法上要使用多个注解校验时。
        3) @SkipValidation 指定某个方法不需要校验。否则所有方法都会使用校验。也可以在检验拦截器中使用validateAnnotatedMethodOnly
        4) 13个内置校验器的注解版本:(注:这些注解都只能用在方法级别上) 具体参数参见Struts2的API或Reference。
      @RequiredFieldValidator
      @RequiredStringValidator
      @StringLengthFieldValidator
      @IntRangeFieldValidator
      @DoubleRangeFieldValidator
      @DateRangeFieldValidator
      @ExpressionValidator
      @FieldExpressionValidator
      @RegexFieldValidator
      @EmailValidator
      @UrlValidator
      @VisitorFieldValidator
      @ConversionErrorFieldValidator

      acc_registe.jsp

      1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
        <%@ taglib uri="/struts-tags" prefix="s" %>
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
        <html>
        <head>
        <title>Struts2中基于XML配置式的校验器使用示例</title>
        </head>
        <body>
        <h3>XML配置式校验器---注册页面</h3><hr/> <div style="color:red"><s:fielderror/></div>
        <form action="acc_registe.action" method="post">
        <table>
        <tr>
        <td>ID</td>
        <td><input type="text" name="id" value="${param.id}"/></td>
        </tr>
        <tr>
        <td>登录名</td>
        <td><input type="text" name="name" value="${param.name}"/></td>
        </tr>
        <tr>
        <td>密码</td>
        <td><input type="password" name="pwd"/></td>
        </tr>
        <tr>
        <td>重复密码</td>
        <td><input type="password" name="pwd2"/></td>
        </tr>
        <tr>
        <td>时间</td>
        <td><input type="text" name="registed_date" value="${param.registed_date}"/></td>
        </tr>
        <tr>
        <td>email</td>
        <td><input type="text" name="email" value="${param.email}"/></td>
        </tr>
        <tr>
        <td>考试成绩</td>
        <td><input type="text" name="score" value="${param.score}"/></td>
        </tr>
        <tr>
        <td colspan="2"><input type="submit" value=" 提交 "/></td>
        </tr>
        </table>
        </form>
        </body>
        </html>

         

      src/struts.xml

        1. <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
          "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts>
          <!-- 请求参数的编码方式 -->
          <constant name="struts.i18n.encoding" value="UTF-8"/>
          <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
          <constant name="struts.action.extension" value="action,do,go,xkk"/>
          <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开 -->
          <constant name="struts.configuration.xml.reload" value="true"/>
          <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开 -->
          <constant name="struts.devMode" value="false"/>
          <!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭 -->
          <constant name="struts.serve.static.browserCache" value="false" />
          <!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
          <constant name="struts.ognl.allowStaticMethodAccess" value="true"/> <!-- 指定由spring负责action对象的创建
          <constant name="struts.objectFactory" value="spring" />
          -->
          <!-- 是否开启动态方法调用 -->
          <constant name="struts.enable.DynamicMethodInvocation" value="false"/> <package name="my" extends="struts-default" namespace="/">
          <action name="acc_*" class="com.javacrazyer.web.action.AccountAction" method="{1}">
          <result name="success">/info.jsp</result>
          <result name="input">/acc_{1}.jsp</result>
          </action> </package> </struts>


      AccountAction.java

      package com.javacrazyer.web.action;
      
      import java.util.Date;
      
      import com.opensymphony.xwork2.ActionSupport;
      
      public class AccountAction extends ActionSupport {
      private static final long serialVersionUID = -1418893621512812472L;
      private Integer id;
      private String name;
      private String pwd;
      private String pwd2;
      private Double score;
      private Date registed_date;
      private String email; public String registe() throws Exception{
      System.out.println("registe-------------------");
      return SUCCESS;
      } public String login()throws Exception{
      return SUCCESS;
      } public Integer getId() {
      return id;
      }
      public void setId(Integer id) {
      this.id = id;
      }
      public String getName() {
      return name;
      }
      public void setName(String name) {
      this.name = name;
      }
      public Double getScore() {
      return score;
      }
      public void setScore(Double score) {
      this.score = score;
      }
      public Date getRegisted_date() {
      return registed_date;
      }
      public void setRegisted_date(Date registedDate) {
      registed_date = registedDate;
      }
      public String getEmail() {
      return email;
      }
      public void setEmail(String email) {
      this.email = email;
      } public String getPwd() {
      return pwd;
      } public void setPwd(String pwd) {
      this.pwd = pwd;
      } public String getPwd2() {
      return pwd2;
      } public void setPwd2(String pwd2) {
      this.pwd2 = pwd2;
      }
      }


      AccountAction-validation.xml [与AccountAction同目录]

      第二个示例:XML配置式校验器---登录和注册页面

      user_login.jsp

      user_registe.jsp

      src/struts.xml


      UserAction.java

      UserAction-user_login-validation.xml


      UserAction-user_registe-validation.xml

      acc2_registe.jsp


      src/struts.xml

      Account2Action.java

4. 过滤

过滤的问题源于URLEncode/URLDecode。字符在从前端到后台, GET方式会自动将URL行Encode,这就会导致空格,加号等字符被转码,所以后台需要再次解码。不过大部分的时候,Encode后并非一定能正确的Decode成当初的字符,所以又出现了BASE64,POST方式的代替方案。

5. 阻止浏览器自动填充password/username表单域

6. 富文本编辑器

7. namespace

8.表单重复提交

9. button/input/submit 提交的方式

10. struts2 Action返回result方式处理

11. 下载文件

struts2表单提单细节处理的更多相关文章

  1. struts2 表单处理

    在这篇教程里我们将探究如何处理表单提交.本文例子介绍: javabean存储表单数据 在action中重写validate方法进行简单的校验 创建一个struts2表单并和javabean匹配 jav ...

  2. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  3. struts2表单验证

    1:采用手工编写代码实现. 通过继承ActionSupport类,然后重写vlidate方法,validate方法会校验跟execute同样签名的方法,当某个数据校验失败时,我们应该调用addFiel ...

  4. struts2表单提交的乱码的问题的解决

    今天碰到一乱码问题,百思不得其解. 最后解决办法是设置了表单的提交方式,将method设置为post,解决问题.虽然默认的提交方式是post.但是如果不显式设置的话,就会出现我所出现的问题. 总结下处 ...

  5. struts2表单提交Date数据无法接收

    问题:在Struts2环境下,提交含有Date类型数据表单,但是在action中没有接收到:String就可以直接接收到: --网络搜索后,说Struts2可以自己转,但是目前没发现有: 然后在狂搜, ...

  6. Struts2 - 表单的重复提交问题

    用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...

  7. 【转】Struts2 表单验证与验证框架

    版权声明:好笔头不如烂记性 https://blog.csdn.net/zsbgood/article/details/81114038 表单数据验证是很常见的功能,通常前端页面会有一次 js验证,但 ...

  8. [JavaWeb基础] 015.Struts2 表单验证框架

    在web开发的过程中,我们经常要用到一些填写表单的操作,我们一般都要在提交表单信息的时候对表单的内容进行验证,struts2给我们提供了简单的实现接口,让我们可以很容易的对表单进行验证.下面讲解下最传 ...

  9. Struts2 表单提交与execute()方法的结合使用

    1.创建web项目,添加struts2支持的类库,在web.xml中配置struts2过滤器. 2.创建名为UserAction的Action对象,并在其中编写execute()方法,代码如下所示: ...

随机推荐

  1. (九)c#Winform自定义控件-树

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  2. 苹果电脑基本设置+Linux 命令+Android 实战集锦

    本文微信公众号「AndroidTraveler」首发. 背景 大多数应届毕业生在大学期间使用的比较多的是 windows 电脑,因此初入职场如果拿到一台苹果电脑,可能一时间不能够很快的上手.基于此,这 ...

  3. 报error:getNetworkFromStore for nid failed while trying to build sandbox for cleanup: network

    docker服务起不来.报error:getNetworkFromStore for nid failed while trying to build sandbox for cleanup: net ...

  4. sed命令及替换文件内容

    一.sed (三剑客老二) 1.sed 替换文件内容 sed  s###g  file  前面两个#中的是原内容,后两个#中的是替换的内容 例:将a.txt文件中的linux替换成java 但是,此时 ...

  5. 阿里分布式事务seata入门(采坑)

    1. 阿里分布式事务seata入门(采坑) 1.1. 前言 seata是feascar改名而来,这是阿里在19年年初开源出来的分布式事务框架,当初刚出来的时候就想研究下了,一直拖到了现在,目前是0.8 ...

  6. Java并发编程知识点总结Volatile、Synchronized、Lock实现原理

    Volatile关键字及其实现原理 在多线程并发编程中,Volatile可以理解为轻量级的Synchronized,用volatile关键字声明的变量,叫做共享变量,其保证了变量的“可见性”以及“有序 ...

  7. cucumber测试框架

    1.1 什么是BDD(行为驱动开发)  首先了解一个概念,BDD(BehaviorDrivenDevelopment:行为驱动开发)为用户提供了从 开发人员和客户的需求创建测试脚本的机会.因此,开始时 ...

  8. HDU 2147

    题意略. 思路: 题中提到的3种操作,一个是将长方形的n减少1,一个是将m减少1,一个是将n和m同时减少1,都是将长方形规模减少的的操作. 现在我们可以知道,(1,1)先手必输:(1,2),(2,1) ...

  9. APPARENT DEADLOCK!!!c3p0数据库连接池死锁问题

    项目进行压力测试的时候,运行大概1小时候,后台抛出以下异常: Nov 9, 2012 1:41:59 AM com.mchange.v2.async.ThreadPoolAsynchronousRun ...

  10. 【selenium】- 自动化测试必备工具FireBug&FirePath

    本文由小编根据慕课网视频亲自整理,转载请注明出处和作者. 1. FireBug FireBug的安装: 如果使用Firefox浏览器的话,推荐使用较低版本,比如27-32.否则会报错. 点击右上角的菜 ...