javaweb 中 el表达式问题总结

来源:互联网 发布:辅助软件定制 编辑:程序博客网 时间:2024/06/03 18:26

javaweb 中 el表达式问题总结


el表达式不能放在 jsp 页面java 代码中, 即不能在 <% %> 中填写el代码。

注意: el表达式中只能获取域属性。要用 pageContext.getAttribute( )来进行获取(或者其他来或获取)。

本文讨论的内容源于使用cookie记录用户名时遇到的问题。如果用户名是英文,则完全没有问题,但是如果是中文名,获取cookie会出现乱码(需要使用urlencoder()和urldecoder()来解决)。但是根据jsp规范,应该尽量少的在jsp页面中出现<% %>的代码块。于是,本文从如下三个角度对代码进行了实现。循序渐进,逐渐完全用标签技术重写了代码。

1. 此处取得cookie的第一种写法,最原始的写法(通过cookie的存取原理实现):
<%        Cookie[] cs = request.getCookies();        Cookie findC = null;        if (cs != null) {         for (Cookie c : cs) {          if ("remusername".equals(c.getName())) {           findC = c;              }         }    }        if (findC == null) {         pageContext.setAttribute("str", "");            } else {         String struser = findC.getValue();        struser = URLDecoder.decode(struser,"utf-8");         pageContext.setAttribute("str", struser);    }%>

将cookie 值显示在jsp 页面上:

   <input type="text" name="username"    value="<%=pageContext.getAttribute("str")%>" />

这里注意取值的时候要从域中进行选取。

通过上面的写法总结下面获取cookie 的通用写法:

<%        Cookie[] cs = request.getCookies();        Cookie findC = null;        if (cs != null) {         for (Cookie c : cs) {          if ("remusername".equals(c.getName())) {           findC = c;              }         }    }        if (findC == null) {            } else {    }%>
2. el 表达式中有11个内置对象,el表达式提出是为了 在jsp 页面中尽量少用 java 代码。 因此为了用el表达式提取出cookie的值可以用如下写法:
                        <c:if test="${cookie.remusername.value!=null}">                            <c:set var="str"      value="${cookie.remusername.value}">                            </c:set>                        </c:if>                        <c:if test="${cookie.remusername.value==null}">                            <c:set var="str" value="">                            </c:set>                        </c:if>                        <input type="text" name="username"                            value="<%=URLDecoder.decode((String) pageContext                        .getAttribute("str"), "utf-8")%>" />
自定义标签技术

这里我们已经尽可能少的使用了java 代码,但是在最终将值显示在页面上的时候仍然使用了<% %>嵌套的java代码。

如果我们想做到完全的无java代码,那么可以通过自定义标签的方式来进行。下面是自定义标签技术的步骤:

关于传统标签的写法我们不再探讨,这里给出简单标签技术的写法:

  • 写一个类extentds SimpleTagSupport 类
  • 写一个tld 文件,描述写好的类
  • 在jsp 页面中引入写好的标签即可

自定义标签需要实现的功能:

  • 控制标签体是否执行
    • 什么都不做就是不执行(doTag中什么都不写)
    • 调用封装着标签体的JspFragment对象的invoke方法就可以执行
      JspFragment fragment = getJspBody( ); 这儿原理是在 setJspBody( ) 进行了赋值操作fragment.invoke( "这里是一个流对象" ); 流对象可以用 getJspContext.getOut(),等价于 pageContext.getOut()获取当前页面的out输出流。实际上要输出标签中的内容,可以直接用 frame.invoke(null) 输出标签体中内容。

  • 控制标签后内容是否执行
    • 什么都不做,后面就会执行
    • throw new skipPageException(); 抛出一个异常,后面就不会执行了
  • 控制重复执行
    for (int i=0 ; i< 5; i++){
    getJspBody().invoke(null) 即可执行标签中内容5次
    }

  • 修改标签体后进行输出

    • 首先想办法拿到标签体的内容,对标签体操作只能: JspFragment fragment = getJspBody();fragment 上面只有一个 invoke 方法怎么办?
      • 声明一个字符流 StringWriter write = new StringWriter();字符输出流,用于标签体内容的输出。
      • fragement.invoke(writer);将标签体数据写到writer输出流中String str = writer.toString();这样就拿到标签体内容。对String 进行各种操作将修改后的String 输出。invoke() 只能将自己的输出流进行输出,外面的输出流不能输出。所以采用传统的输出方式进行输出,getJspContext().getOut().Write(str);
    • 为标签添加属性的步骤在标签处理类中添加一个javaBean属性,这个属性就是要添加的标签的属性,注意:要对外提供一个setXXXd 的方法。
    • 在tld文件中对该标签进行描述以上面循环执行的标签为例,如下描述:在类javaBean中添加times(表示次数)属性

      public int times;public void setTimes (int times){                 this.time = time}在tld文件中添加如下代码}

下面是tld文件中需要设置的各项属性:

        <name></name>        <tag-class</tag-class>        <body-content><body-content>        <attribute>        <name></name>//参数名称        <requirest>true</requirest>//是否必须        <reexprvalue></reexprvalue //是否支持正则表达式        <tag></tag//什么类型        </attribute>
3. 运用上面的自定义标签技术,可以得到我们的第三种方法(完全标签化,转义java代码):

首先建一个类继承simpleTagSupport类

        public class UrlEncodingTag extends SimpleTagSupport {            private String content;            private String encode;            public void setContent(String content) {                this.content = content;            }            public void setEncode(String encode) {                this.encode = encode;            }            public void doTag() throws JspException, IOException {                String str = URLDecoder.decode(content, encode == null ? "utf-8" : encode);                getJspContext().getOut().write(str);//getOut 只是拿到了一个输出流,要输出还需要调用write方法            }        }

其次,写一个tld 文件用于描述(tld文件要建在web-inf目录下除了lib和classes目录外的任意目录中)

        <?xml version="1.0" encoding="UTF-8"?>        <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"            xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">            <tlib-version>1.0</tlib-version>            <short-name>Mydecoder</short-name>            <uri>http://www.haoqiang.decoder</uri>            <tag>                <name>MyDecoder</name>                <tag-class>com.haoqiang.tag.UrlEncodingTag</tag-class>                <body-content>empty</body-content>                <attribute>                    <name>content</name>                    <required>true</required>                    <rtexprvalue>true</rtexprvalue>                    <type>java.lang.String</type>                </attribute>                <attribute>                    <name>encode</name>                    <required>false</required>                    <rtexprvalue>true</rtexprvalue>                    <type>java.lang.String</type>                </attribute>            </tag>        </taglib>

最后在jsp页面中应用该标签即可

<input type="text" name="username"  value="<Mydecoder:MyDecoder content="${cookie.remusername.value}"  encode="utf-8"/>" />

注意,在jsp页面引入其他标签的时候,无论是jstl库或者是自定义的标签,都应该首先用标签将其先引入进来才能使用,不可忘记!

本文由zuanny总结,转载请声明出处,谢谢大家~~

0 0