zoukankan      html  css  js  c++  java
  • 本文为转载Web常使用的功能经验笔记第1季 转载自刘岩

    Web常使用的功能经验笔记第1 

    刘岩

    Emailsuhuanzheng7784877@163.com

    1. 前言

    Apache的Struts2已经是很流行的MVC Web框架了,很多Web开发人员都是使用它做为Web框架。它是在 struts 和WebWork的技术基础上进行了合并,全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。因为Struts 2和Struts 1有着太大的变化,但是相对于WebWork,Struts 2只有很小的变化。像Struts2的常用配置功能笔者就不在说了,在此结合作者的Web相关技术(Struts2、JSTL、EL……)使用经验做个总结,希望与您有个共鸣。

    1. 判断标签<s:if>

    当在request域里面的对象需要判断的时候,可以选用<s:if>,当然Struts2的所有标签都必须在一个Action转向后才能使用的,直接访问一个JSP就使用Struts2的标签,报错。

    例如:

    <s:if test="%{#session.customer==null}">

        <A class=buy-btn href="#" title="登录才能抢购">抢购</A>

    </s:if>

    <s:if test="%{#session.customer!=null}">

        <A class=buy-btn

            href="proAction!buyProductBefor.action?products.id=${products.id}"

           title="登录才能抢购">抢购</A>

    </s:if>

    1. 在页面中访问变量(#、%、$)

    OGNL是通常要结合Struts 2的标志一起使用。主要是#、%和$这三个符号的使用。

    一般使用JSP内置对象域的变量的时候(application、session、request、parameters)都需要使用Struts标签+#来进行访问,一般用于访问Session里面的变量。

    例如:

    <s:if test="%{#session.customer!=null}">

    或者

    <s:property value="%{#application.myApplicationAttribute}" />
    <s:property value="%{#session.mySessionAttribute}" />
    <s:property value="%{#request.myRequestAttribute}" />
    <s:property value="%{#parameters.myParameter}" />

    在Struts2标签中访问内置对象的变量的时候前面得用%{}将变量括起来。

    如果在Action中被注入的对象在ValueStack域中的时候,在页面中可以直接采用el表达式来访问变量。

    例如:

    <TD><STRONG class="original">${products.sourcePrice}</STRONG></TD>

    如果变量显示的在Action中直接赋值(set)给了request、session域中后,在页面也可以直接使用el表达式来进行访问,但是这里仅仅只是显示,并不能在Struts2标签中判断、计算等。代码如下。

    你好,${session.customer.name}

    一般Struts2标签要配合OGNL表达式一齐使用,包括一些运算、判断、取子字符串等等。在此引用别人博客(http://www.javaeye.com/problems/51144)上的一段话

    “#”主要有三种用途:
    1.访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:  

    名称 作用 例子
    parameters:包含当前HTTP请求参数的Map

    #parameters.id[0]作用相当于request.getParameter("id")

    Request:包含当前HttpServletRequest的属性(attribute)的Map

    #request.userName相当于request.getAttribute("userName")

    Session:包含当前HttpSession的属性(attribute)的Map

    #session.userName相当于session.getAttribute("userName")

    Application:包含当前应用的ServletContext的属性(attribute)的Map #application.userName相当于application.getAttribute("userName")

    Attr:用于按request > session > application顺序访问其属性(attribute)

    #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止

    2.用于过滤和投影(projecting)集合,如books.{?#this.price<100};
    3.构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。

    “%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。

    “$”有两个主要的用途,用于在国际化资源文件中,引用OGNL表达式。在Struts 2配置文件中,引用OGNL表达式。

    1. JSTL格式化数字

    一般用到整数、小数格式化的时候可以直接用JSTL来处理。

    使用jstl的fmt标签可以对页面的值进行格式化、国际化显示等功能。

    引入标签:<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

    保留整数,小数后一位永远是0

    <fmt:formatNumber value="${(products.nowPrice/products.sourcePrice)*10}" pattern="#.0" />折 </STRONG>

    保留两位小数

    <!--保留2位小数点,格式化数字-->

    <STRONG>£¤<fmt:formatNumber value="${products.sourcePrice-products.nowPrice}" pattern="#.##" minFractionDigits="2" /></STRONG>

    读取资源文件

    <fmt:message key="global.add" />

    1. Struts2日期标签格式化日期

    代码如下

    <TD class=order-num>

    <s:date name="#orderProductListVar.orders.orderDate" format="yyyy-MM-dd HH:mm:ss" />

    </TD>

    显示出来得值就是2011-01-10 21:09:26

    1. 利用Struts2错误标签显示Action中显示发生的错误

    <s:fielderror>

        <s:param>errorMessage</s:param>

    </s:fielderror>

    其中errorMessage是Action中错误域中的key。

    1. 利用Struts2标签得到字符串长度和截取子字符串

    <!--判断字符串长度-->

    <s:if test="%{#productsListVar.productMess.length()>=40}">

        <s:property value="#productsListVar.productMess.substring(0,40)" />...

    </s:if>

    <s:else>

        <s:property value="#productsListVar.productMess" />

    </s:else>

    1. Struts2的JSON插件,让Struts2也REST起来

    利用Struts2的json插件——struts2-json-plugin-2.1.8.jar(在Struts-all包中有此插件包)

    首先看struts.xml的配置

    <!DOCTYPE struts PUBLIC

            "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

            "http://struts.apache.org/dtds/struts-2.0.dtd">

    <struts>

     

        <!-- 配置Struts2应用的编码集 -->

        <constant name="struts.objectFactory" value="spring" />

        <constant name="struts.i18n.encoding" value="UTF-8" />

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

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

     

        <!--基类包-->

        <package name="baseAdminJsonackage" extends="json-default"

           abstract="true">

     

           <global-results>

     

               <!--没有权限-->

               <result name="hasNoToken" type="redirect">

                  hasNoToken.jsp

               </result>

     

               <!--进入页-->

               <result name="input" type="redirect">input.jsp</result>

     

               <!--错误页面-->

               <result name="error" type="redirect">error.jsp</result>

     

               <!--ajax返回Json信息-->

               <result name="successJson" type="json"></result>

           </global-results>

     

        </package>

     

        <!--后台管理相关-->

        <package name="administrator" extends="baseAdminJsonackage">

     

           <!--用户管理-->

           <action name="userAction"

               class="module.system.action.UserAction">

               <result name="success" type="redirect">

                  /admin/jqgrid.jsp

               </result>

               <result name="loginSuccess" type="redirect">

                  /admin/main.jsp

               </result>

               <result name="loginError" type="redirect">

                  /admin/login.jsp

               </result>

           </action>

     

        </package>

    </struts>

    下面来看UserAction的部分代码:

    public class UserAction extends BaseAction {

     

    public List objectList;

     

        @JSON

        public List getObjectList() {

           return objectList;

        }

        public void setObjectList(List objectList) {

           this.objectList = objectList;

        }

        /**

         * ------------------------临时测试用

         *

         * @return

         */

        public String listTemp() {

     

           // 总记录数

           objectList = uxAdminDao.findAll();

     

           return "successJson";

        }

    }

    上面是返回到”successJson”的结果中,在web前端只要通过任何的http请求到

    userAction! listTemp.action,返回的结果中就可以获得objectList变量的json格式字符串。前端如何解析,就是前端的事情了。

    1. Struts2的拦截器

    它一般作为Session建权(建立权限)用,在拦截器中进行session的判断。

    引用一段别人的代码

    先看拦截器配置

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

             <interceptors>

                 <interceptor name="loginAuth"

                       class="XXX.LoginAuthInterceptor" />

                 <interceptor-stack name="completeStackWithLoginAuth">

                       <interceptor-ref name="loginAuth" />

                       <interceptor-ref name="defaultStack" />

                 </interceptor-stack>

             </interceptors>

             <default-interceptor-ref name="completeStackWithLoginAuth" />

             <global-results>

                 <result name="login">/userLogin/error.jsp</result>

                 <result name="expire">/modifyPW/modifyPW.jsp</result>

                 <result name="forbid">/userLogin/forbid.jsp</result>

             </global-results>

    </package>

    之后编辑拦截器类

    @SuppressWarnings("serial")

    public class LoginAuthInterceptor extends AbstractInterceptor {

        @Override

        public String intercept(ActionInvocation actionInvocation) throws Exception {

            // 获得会话中的用户身份字段

            Map session = actionInvocation.getInvocationContext().getSession();

            String user = (String) session.get(ISysParam.SESSION_USER);

            if (null == user) {

                return Action.LOGIN;

            } else {

                StringBuffer invokeMtd = new StringBuffer(actionInvocation

                        .getProxy().getNamespace());

                invokeMtd.append("/"

                        + actionInvocation.getInvocationContext().getName());

                String role = (String) session.get(ISysParam.USER_ROLE);

                //测试代码  如果是用户名是admin 则不进行权限判断

    //            if(user.equals(ISysParam.ROLETYPE_ADMIN)){

    //                return actionInvocation.invoke();

    //            }

                /*

                 * 得到该所能操作的名称空间 if(可以访问当前的名称空间){ 跳出拦截器 else{ 转到没有权限的页面 } }

                 */

    //            if (role.contains(invokeMtd.toString())) {

    //                return actionInvocation.invoke();

    //            } else {

    //                return "forbid";

    //            }

                // if (!user.getUserName().equals(ISysParam.ROLETYPE_ADMIN)) {

                // // 对非ADMIN用户,检查模块访问权限

                // if (!chkPrivilege()) {

                // log.debug(user.getUserName() + ":" +ISysParam.OPER_CANCEL);

                // return FORBID;

                // }

                // }

                // return actionInvocation.invoke();

                // }

                 return actionInvocation.invoke();

            }

        }

    }

    之后的流程配置如下

    <package name="xxx" namespace="/xxx"

            extends="xxx-default">

            <action name="*" method="{1}" class="XXXAction">

                <result name="input">{1}.jsp</result>

                <result name="error">{1}.jsp</result>

                <result name="success">{1}.jsp</result>

            </action>

        </package>

    <package name="xxx2" namespace="/xxx2"

            extends="xxx-default">

             <action name="*" method="{1}" class="XXX2Action">

                 <result name="input">{1}.jsp</result>

                 <result name="error">{1}.jsp</result>

                 <result name="success">{1}.jsp</result>

             </action>

    </package>

    自己定义

    <package name="myPkg" abstract="true" extends="struts-default"></package>

    在这个包下面定义拦截器, 这个包下面定义拦截器栈的引用, 引用defaultStack和你自己定义的拦截器!然后你需要用这个拦截器的包都继承这个包就好了!

    1. Struts2的防刷新提交机制

    在Struts2中解决表单的重复提交感觉还算简单。

    token: 在活动中检查合法令牌(token), 防止表单的重复提交;

    tokenSession: 同上, 但是在接到非法令牌时将提交的数据保存在session中;

    首先在struts.xml中配置Action如下信息

    <!-- 评论Action -->

    <action name="commentsAction" class="action.CommentsAction">

             <result name="invalid.token" type="redirect">productAction!list.action

             </result>

             <interceptor-ref name="defaultStack">

                       <param name="workflow.excludeMethods">default</param>

             </interceptor-ref>

             <interceptor-ref name="token">

                       <param name="includeMethods">add,update</param>

             </interceptor-ref>

             <result name="listByProductsId">/admin/page/commentsList.jsp</result>

             <result name="add">/admin/page/commentsAdd.jsp</result>

             <result name="update">/admin/page/commentsUpdate.jsp</result>

    </action>

    在这个Action中引用了2个拦截器,一个是默认的注入拦截器defaultStack,另一个就是令牌拦截器token,之后还定义了一个重复提交后的返回地址invalid.token。

    之后在页面表单form中加入<s:token></s:token>就可以了。

    1. <meta http-equiv="X-UA-Compatible" content="IE=7" />的意思

    X-UA-Compatible是针对ie8新加的一个设置,对于ie8之外的浏览器是不识别的,这个区别与content="IE=7"在无论页面是否包含<!DOCTYPE>指令,都像是使用了 Windows Internet Explorer 7的标准模式。而content="IE=EmulateIE7"模式遵循<!DOCTYPE>指令。对于多数网站来说,它是首选的兼容性模式。

    目前IE8尚在测试版中,所以为了避免制作出的页面在IE8下面出现错误,建议直接将IE8使用IE7进行渲染。也就是直接在页面的header的meta标签中加入如下代码:

    <meta http-equiv="X-UA-Compatible" content="IE=7" />

    这样我们才能使得页面在IE8里面表现正常!

    1. Js比较数值大小

    在JS中比较数字大小的时候一般人都会用

    If(a >= b){

        ……

    }

    这是错误的,这比较是从第一个字符串开始比较。

    应该用

    If(a - b >= 0){

        ……

    }

    进行数值比较

    声明:本文为网络转载,如果侵犯版权,将及时删除……不负任何法律责任。

    I believe that we are who we choose to be. Nobody‘s going to come and save you, you‘ve got to save yourself. 我相信我们成为怎样的人是我们自己的选择。没有人会来拯救你,你必须要自己拯救自己。
  • 相关阅读:
    c# 字符串中某个词出现的次数及索引
    c# 冒泡排序
    WCF 高级知识
    Web Api基础知识
    Web Services基础知识
    WCF Demo
    IIS部署WCF常见错误
    IIS部署WCF
    IIS部署WCF错误
    WCF基础知识
  • 原文地址:https://www.cnblogs.com/caroline/p/2048653.html
Copyright © 2011-2022 走看看