• Java 笔记20180123


    在批量添加数据时候采用List或者Map或者Set
    Set<Student> students = new Set<Student>();
    // 客户端验证:js;服务器端验证:必须有
    1对动作类中的所有方法进行验证
    a.动作类需要继承ActionSupport方法,覆盖public void validate();
    b.方法内部编写你的验证规则,出现错误信息时候想addFieldError中添加错误信息
    动作类就是模型:
    public void validate(){
    if(birthday==null||"".equals(birthday))
    addFieldError("birthday","请输入xxx");
    }
    动作类和模型分开:
    public void validate(){
    if("".equals(student.getUsername().trim()))
    // 空格不认为是空的
    addFieldError("student.birthday","请输入xxx");
    }

    // 只针对某一方法进行验证
    public String regist(){
    System.out.println("abc");
    return SUCCESS;
    }
    public void validateRegist(){
    if("".equals(student.getUsername().trim()))
    // 空格不认为是空的
    addFieldError("student.birthday","请输入xxx");
    }
    2.声明是验证:
    将验证信息写到配置文件中,用的比较多
    错误视图和消息验证同编程是验证一直
    a.针对动作类中的所有动作方法进行验证
    动作类就是模型
    在动作类所在的包中:建立一个 动作类名-validation.xml配置文件
    <validators>
    <!--field指定要验证的字段名,name为字段的名字-->
    <field name="birthday">
    <!--指定验证规则:type是验证规则,required是验证输入内容不能为null-->
    <field-validate type="required">
    <!--不符合错误规则的消息提示-->
    <message>请输入---</message>
    </field-validate>
    </field>
    </validators>
    b.针对动作类中指定的动作方法进行验证
    在动作类所在的包中建立:动作类名-动作名-validation.xml配置文件
    验证功能是validation拦截器控制的,错误回显是通过workflow控制的

    <![CDATA[]]>标记所包含的内容将会被表示为纯文本,比如<![CDATA[<]]>表示为“<”
    在xml有些字符是不能被直接传入的,需要进行转译操作,比如“<”,“>”,“&”,直接传入xml会被报错
    要转译成“&lt;”,“&bt;”,“&amp;”实体,这样才能被保存到xml文档中。
    那么,在程序读取的时候,解析器会自动转换为“<”,“>”,“&”,比如:
    <age> 20 < 30</age>
    要写成:<age> 20 &lt; 30</age>
    注意:
    1)注意序列字符之间不能有空格;
    2)必须以“;”结束;
    3)单独以“&”开始不被认为是转译
    4)区分大小写
    在xml需要进行转译的有:
      (1)&   &amp;
      (2)<   &lt;
      (3)>   &gt;
      (4)"   &quot;
      (5)'   &apos;
    所以:使用<![CDATA[]]>用来包含不被xml解析器解析的内容
    注意:
      (1) 此部分不能再包含”]]>”;
      (2) 不允许嵌套使用;
      (3)”]]>”这部分不能包含空格或者换行。
      最后,说说<![CDATA[]]>和xml转移字符的关系,它们两个看起来是不是感觉功能重复了?
      是的,它们的功能就是一样的,只是应用场景和需求有些不同:
      (1)<![CDATA[]]>不能适用所有情况,转义字符可以;
      (2) 对于短字符串<![CDATA[]]>写起来啰嗦,对于长字符串转义字符写起来可读性差;
      (3) <![CDATA[]]>表示xml解析器忽略解析,所以更快。

    在声明是验证的配置文件中:动作类名-动作名-validation.xml
    <validators>
    <field name="username">
    <field-validate type="regex">
    <param name="regexExpression"><![CDATA[[A-Za-z]{3,8}]]></param>
    <message>输入的username必须为3-8字符</message>
    </field-validate>
    </field>
    <field name="password">
    <field-validate type="requiredstring">
    <message>请输入密码</message>
    </field-validate>
    <field-validate type="regex">
    <param name="regexExpression"><![CDATA[/d{3,8}]]></param>
    <message>你的密码必须有3-8位数字组成</message>
    </field-validate>
    </field>
    <!--必须选择性别-->
    <field name="sex">
    <field-validate type="required">
    <message>请选择性别</message>
    </field-validate>
    </field>
    <field name="email">
    <field-validate type="email">
    <message>请输入正确的邮箱</message>
    <field-validate>
    </field>
    <field name="grade">
    <field-validate type="int">
    <param name="min">15</param>
    <param name="max">100</param>
    <message>成绩必须在${min}~${max}之间</message>
    </field-validate>
    </field>
    </validators>

    struts2的拦截器
    modelDriven:模型驱动
    ServletConfig:获取servletAPI
    staticParams:静态参数注入
    params:动态参数注入
    validate:输入验证,声明之验证

    自定义拦截器:和过滤器的功能差不多,充当保安的作用
    a.编写一个类,继承 AbstractInterceptor抽象类
    public class Demo1Interceptor extends AbstractInterceptor{
    // 返回值:最终结果的返回值,就是一个逻辑结果视图,对应struts.xml的result
    public String intercept(Invocation invocation){
    System.out.println("拦截器前");
    String rtValue = invocation.invoke();// 方向
    System.out.println("拦截器后");
    return rtValues;
    }
    }
    b.配置拦截器
    <package name="p1" extend="struts-default" namespace="/user">
    <interceptors>
    <!--定义拦截器-->
    <interceptor name="Demo1Interceptor" class="com.deng.Demo1Interceptor/>
    <interceptors>
    </package>
    c.使用拦截器
    <action name="Demo1Action" class="com.deng.Demo1Action">
    <interceptor-ref name="Demo1Interceptor"></interceptor>
    <result>/1.jsp</result>
    </action>
    ==编写一个执行动作方法前验证用户是否登录的拦截器
    a.编写一个类,对所有动作都执行拦截的拦截器
    public class LoginCheckInterceptor extends AbstractInterceptor{
    public String intercept(ActionInvocation invocation) throws Exception{
    // 通过session检测你有没有登录
    Session session = ServletActionContext.getRequest().getSession();
    Object obj = session.getAttribute("user");
    // 没有登录,转向登录界面
    if(obj==null){
    return "login";
    }
    // 登录,方形
    String rtValue = invocation.invoke();
    return rtValue;

    }
    }
    // 上传文件的要求
    1.form的method方法必须是post类型
    2.表单提交的enctype类型必须为multipart/form-data
    3.input type="file" 输入与类型为file
    文件上传
    public class Demo1Action extends ActionSupport{
    private String name;
    private File photo;// 必须是File类型,名字对应表单的输入与
    private String photoFileName;// 上传文件的文件名,必须为XXXFileName
    private String photoContentType; // 上传文件的文件类型,必须为XXXContentType
    public String uploadFile(){}
    }
    上传失败时候,会提示错误
    <s:actionerror/>
    修改上传文件的总大小,在struts.xml
    <constant name="struts.multipart.maxSize" value="10247847"></constant>
    限制上传的文件类型
    allowedTypesSet:允许上传的MIME类型,多个用逗号隔开
    allowedExtendsSet:允许上传的扩展名,多个用逗号隔开
    <action name="uploadFile" class="com.deng.Action" method="uploadFile">
    <interceptor-ref name="defaultStack"
    <param name="fileUpload.allowedExtends">.jpg,.gif,.png</param>
    </interceptor>
    </cation>
    文件下载:结果类型的使用
    名字为stream的结果类型处理文件下载
    1.动作类遵守一定的规范
    public class DownloadAction extends ActionSupport{
    private InputStream inputStream;// 建立一个输入流
    private String fileName;
    public String downloadFile(){
    // 找到该文件的真实地址
    String realPath = ServletActionContext.getServletContext().getRealPath("/pic.jpg");
    // 获取文件名
    fileName = URLEncoding(FilenameUtils.getName(realPath),"UTF-8");
    // 放到输入流中
    inputStream = new FileInputStream(inputStream);

    return SUCCESS;
    }
    }
    2.编写struts.xml中的配置
    <action name="fileDownload" class="com.deng.fileDownload" method="downloadFile">
    <result type="stream">
    // 指定动作类中的输入流的属性名
    <param name="inputName>inputStream</param>
    // 通知浏览器以下载的方式打开,获取文件名的方式是OGNL表达式,调用动作类中的getFileName方法
    <param name="contentDisposition">attachment;filename=${fileName}</param>
    // MIME类型
    <param name="contentType">application/octet-stream</param>
    </result>
    </action>
    OGNL表达式:在struts2中使用OGNL表达式,必须要要放到struts2的标签中
    功能:
    1.支持对象方法调用,如XXX.doSomething();
    <s:property>相当于JSTL的<c:out>
    调用任意对象的任意方法
    <s:property value="abc".length()/>
    2.类静态方法调用
    3.访问OGNL上下文和ActionContext
    4.操作集合对象

    context上下文
    context map包括:
    key value
    application ServletContext中的所有属性attributes
    session HttpSession中的所有属性attributes
    value stack 它是一个list
    action 动作类
    request ServletRequest中的所有属性
    parameters Map map = request.getParameterMap()
    attr 从四大与范围中搜索,${}
    动作类的生命周期:每次访问都会重新创建动作类的实力,还会创建ActionContext,valueStack实力,一直保存在你的线程中
    ContextMap和root站组成了值站
    ServletContext sc = ServletActionContext.getServletContext();
    ActionContext ac = ActionContext.getContext();

    1.ActionContext API:操作contextMap中的数据
    // ActionContext中常用的API
    public class Demo1 extends ActionSupport{
    public String m1(){
    // 如何得到ActionContext的实力:绑定到当前线程中
    //
    ActionContext ac = ActionContext.getContext();
    // 想ActionContext存放数据
    ac.put("p1","p1value");
    // 取出数据
    String s = (String)ac.get("p1");

    // 获取valueStack的值
    ValueStack vs = ac.getValueStack();

    // 想HttpSession中存放属性
    HttpSession session = ActionContext.getRequest().getSession();
    session.setAttribute("a1","a1value");
    // 从HttpSession中获取相关的属性
    String s = (String)ac.getSession().get("a1");

    // 获取请求参数
    String[] a = (String [])ac.getParameters().get("name");

    // 获取当前动作的名称
    ac.getName()

    // 获取应用范围的数据
    ServletContext sc = ServletActionContext.getContext();
    sc.setAttribute("a2","a2value");
    String s = (String)ac.getApplication().get("a2");


    }
    }
    OGNL其他用法
    1.获取jsp页面中的contextMap/root的值.获取contextMap中的数据,OGNL要用#开头
    ActionContext.getContext().put("a1","a1value");
    获取contextMap中的数据
    <s:property value="#a1">
    2.获取根(list)中对象的属性,直接写属性的名称,会从栈顶直接往下找
    public String m1(){
    ValueStack vs = ActionContext.getContext().getValueStack();
    Calender c1 = Calender.getInstance();
    c1.set(2000,01,22);
    vs.push(c1):// 入栈
    }
    获取数据
    <s:property value="month">
    OGNL其他用法
    1.在jsp中可以使用OGNL取得数据,也可使用el表达式获取数据
    2.在jsp页面中构造list和map对象
    构造list对象
    <s:property value="{a,b,c}"/>
    构造map对象
    <s:property value="#{'a':'1','b':'2','c':'3'}"
    <s:radio name="gender" list="#{'1':'男','0':'女'}"></s:radio>
    <s:checkboxlist name="hobby" list="{eat,sleep,play}"></s:checkboxlist>
    3.OGNL和字符串之间的转换
    4.在配置文件xml或者properties 文件中也可以使用OGNL,形式是:${ognl}
    <param name="Disposition">attachment;filename="${fileName}"</param>

    struts2的常用标签
    // property 输出数据到页面
    <s:property value="name"/>
    // value 不写,输出栈顶对象
    <s:property/>
    // set 放数据,默认放到action
    scope:application|session|request|action|page
    <s:set value="value1" var="v1" scope="session"></s:set>
    <s:set value="value2" var="v2"></s:set>
    contextMap:<s:property value="#v2"/>
    requestScope:<s:property value="#request.v2"/>
    // bean:给一个类起一个名字,将该对象放入contextMap中
    <s:bean name="java.util.Date" var="now"></s:bean>
    <s:property value="#now.time"/>
    // action:指向一个动作
    <s:action name="Demo2" executeResult="true"></s:action>
    // iterator:forEach迭代
    <table border="1">
    <tr>
    <th>key</tr>
    <th>value</th>
    </tr>
    <!--指定了var:把当前遍历的元素放入到contextMap中,me是每一个变量实体-->
    <s:iterator value="#request" var="me">
    <tr>
    <th><s;property value="#me.key"/></tr>
    <th><s:property value="#me.value"/></th>
    </tr>
    </s:iterator>
    </table>

    <table border="1">
    <tr>
    <th>key</tr>
    <th>value</th>
    <th>序号</th>
    </tr>
    <!--指定var:把当前遍历的元素存放到根站的栈顶,Map.entry
    status属性:指向一个对象,包含遍历元素的信息,放到contextMap中,该对象具有以下方法
    isOdd
    isEven
    isLast
    isFirst
    getIndex
    getCount
    -->
    <s:iterator value="#request" status="s">
    <tr class="${s.odd?'odd':'even'}">// <tr class="<s:property value='#s.odd?"odd":"even"'/>"
    <th><s;property value="key"/></tr>
    <th><s:property value="value"/></th>
    <th><s:property value="#s.count"/></th>
    </tr>
    </s:iterator>
    </table>
    <!--url结合参数使用-->
    <s:url action="act1" url="u1">
    <s:param name="username" value="hello"><s:param>e
    </s:url>
    <a href="${u1}">click</a> // 相当于调用getU1方法
    // 同时采用用你的的方
    <s:u action="ac2">click too <s:param name="username" value="hello too"></s:param></s:u>
    <s:textfield name="username" label="用户名" requiredLabel="true"></s:textfield>
    <s:radio name="sex" list="{'nan','nv'}" value="nan" label="性别"></s:radio>

    <%
    List<Customer> customers = new ArrayList<Customer>();
    customers.add(1,"张三");
    customers.add(2,"李四");
    customers.add(3,"王五");
    request.setAttribute("customers",customers);
    %>
    <s:checkboxlist name="ns" list="#required.customers" listKey="id" listValue="name" label="你的顾客"></s:checkboxlist>
    <s:select name="ciyt" list="#{'bj':'北京','sh':'上海'}" label="城市"></s:select>
    <s:select name="ylike" list="#request.customers" listKey="id" listValue="name" headerKey="" headerValue="--请选择--"></s:select>
    防止表单重复提交
    <action name="DemoAction" class="com.deng.DemoAction" method="m1">
    <interceptor-ref>defaultStack</interceptor-ref>
    <interceptor-ref>token</interceptor-ref>
    <!--结果视图是token拦截器转向的-->
    <result name="invalid.token">/msg.jsp</result>
    </action>
  • 相关阅读:
    VMWARE虚拟机提示 "您正在运行的此虚拟机已启用侧通道缓解。侧通道缓解可增强安全性,但也会降低性能""
    appSettings 配置节中不存在项"formldStr"
    PVC圆管直接跑MPS计划需求单的部件材料用量为空
    [转]Linux安装tomcat
    mysql磁盘满
    Linux开机自启动
    mysql主从配置
    tar解压与压缩
    ubuntu中的root用户
    mysql二进制日志
  • 原文地址:https://www.cnblogs.com/demo-deng/p/8336952.html
Copyright © 2020-2023  润新知