IT忍者神龟之jsp标签、EL表达式、JSTL标签、函数、自定义标签

来源:互联网 发布:苹果usb共享wifi网络 编辑:程序博客网 时间:2024/05/23 17:16

案例中的分帧页面:frameset不能再body

将多个页面用帧标签组合

Javacript:void(0)取消默认的行为

Onclick="hidden(document.getElementById(d1))"

点击事件:隐藏组件

<script>

Function hidden(div){

Div.style.display=div.style.display='block'?'none':'block';

}

</script>

 Jsp中使用javabean:

<jsp:useBean>在指定的域查找将javabean,不存在则实例化一个javabean存到指定的域;

例子:<jsp:useBean id="person" class="cn.beijing.codmain.Person" scope="page"></jsp:useBean>//class要为bean的完整类名,域默认为pageContext域。Bean实例化后保存到pageContext域。

 <jsp:useBean>便签之间带标签体,只有在创建bean的时候才执行(刷新:域为request,则每次会话都执行标签体,域为session30分钟内,仅第一次访问执行)

<jsp:setProperty>设置bean的属性

例子:<jsp:setPropety name="person" property="name" value="xxx"/>//value8中基本数据类型会自动进行数据转换,不支持复杂类型转换,value可以为表达式

<jsp:setProperty name="person" property="name" param="name"/>//用请求参数作为属性的值(将请求参数封装到了bean)

<jsp:setPropety name="person" perperty="*"/>//将所有的请求参数的值封装到bean 中(通过反射)

<jsp:getProperty>得到bean的属性

例子:<jsp:getProperty name="person" property="name"/>

属性可能为NULL,要先判断,再输出,后面可以用el 表达式解决

Jsp2中开发模式:

Jsp+javabean:jsp 处理可显示数据, bean封装数据,用于业务逻辑不太复杂的WEB应用

 案例:计算器

四舍五入:

BigDecimal类是大数字,setScale(int,int),设置精度和舍入模式

BigDecimal bd=new BigDecimal(thi.resutl);//将数字封装到big

bd=db.setScale(2,BigDecimal.ROUND_HALF_UP);

This.resutl=bd.doubleValue();

Servlet+jsp+javabean:servlet处理请求,jsp显示,bean封装数据

三层架构:

Web层( jspservlet),业务处理层(service负责业务逻辑),数据访问层(dao负责数据处理),3层通过javaBean衔接

层与层之间的解耦:上层调用接口,下层实现接口

通过报名组织接口和实现:cn.beijing.service;cn.beijing.service.impl;

项目目录:请求通过servlet转发到(forwardjsp。为防止用户直接访问jsp ,应该将 jsp放在web-inf目录下的文件夹中。(JSP调用交给服务器处理。浏览器不能直接访问了)

EL表达式和JSTL标签:

取出域中的数据:${name}

${标识符}//原理:内部调用 pageContext.findAttribute() ,从 pageContext,request,session,application域中查找数据,如果不存在,就返回“”;

获取bean的属性:${person.age}

获取bean中的bean中的属性:${person.address.city}

取集合中的数据:$(lsit[0].age);${liat[1]};${map.aa}(key不能为数字)

 El表达式map集合中取数据,点不行时,用${map["1"]};

其他常用EL表达式:

动态配置地址:

<a href="${pageContext.request.contextPath}/1.jsp">点点</a>

El表达式:

El表达式内不能嵌套EL表达式,后面不用加分号

4个作用:

1.获取数据:从4个域中查找数据(各种集合),替换jsp中的脚本表达式

2.执行运算:

支持数字相加,不支持字符串相加

支持关系运算符(大于,小于,等于。。)和逻辑运算符(与或等。。。)(参考PPT${1==1}//返回truefalse

Empty运算符:检查是否为NULL或“”,${!empty(list)}

二元表达式:${!user=null?user.name:""}

二元表达式应用:回显数据<input type="radio" name="gender" value="male"

${user.gender=='male'?:'checked':''}></br>

[].运算符:点不行就用[]

3.获得WEB开发常用对象:EL表达式语言中定义了11个隐士对象。可以直接用对象

pageContext//可以拿到其他域对象

${pageScope}//返回page域中用于保存数据的MAP集合

${pageScopte[i]},${pageContext.key}

pageScope,requestScope,sessionScope,applicationScope

${sessionScope.user==null}//检查用户是否登录

Param(所有请求参数MAP集合),paramValues(针对一个请求参数时,返回String[])header(所有请求头MAP集合),headerValues(返回String[]),cookie,initParam(WEB应用所有初始化参数MAP)

${header.Accept},${header["Accept-encoding"]}

4 .ELJAVA方法:EL自定义函数 

使用:写一个静态方法,TLD(参考 tomcat中的例子)中描述方法(function),导入标签库,在EL中调用即可。

${user==null?"对不起":fx:join("欢迎你",user.name)}

可用EL函数优化,HTML转义

JSTLEl函数什么时候用?JSTL标签可以移除所有的JAVA代码,El函数只能移除与 开发无关的外部代码。如  涉及到域时就只能用JSTL 标签

如果不解析El可以加<%@page isIgnored="true"%>

 

SUN公司El函数库:主要都是操作字符串

要导入sun公司EL 函数库

fn:toLowerCae//转小写${fn:toLowerCae("AAAA")}

fn:toUpperCase//转大写

fn:trim//去掉两边的空格

fn:length//返回集合和数组大小,常常和JSTL标签合用

用函数迭代集合:

<c:foreach var="index" begin="0" end="${fn:length(list)}">

${list[index]}

</c:foreach>

如果为NULL,返回0

Fn:split//以字符串种的特定字符分割字符串,返回字符串数组

${fn:split("www.hd.us",".")}

Fn:join//以指定的字符串将某个字符串数组中的所有元素组合成字符串。

String[] arr={"www","hd","us"};

${fn:join(arr,".")}//结果为www.hd.us

应用:检测一个字符串数组中是否包含某个字符串,先组合成字符串,然后检测

Fn:contains//字符串种是否包含指定的字符串,大小写敏感

Fn:containsIgnoreCase//忽略大小写

${fn:contains(fn:join(user.likes,","),"sing")?'checked':''}

Fn:indexOf//返回一个字符在一个字符串种第一次出现的位置

Fn:startsWith//是否以指定字符串开头

Fn:endsWith//是否以指定字符串结尾

Fn:replace("www fn "," ",".")//替换字符串

Fn:subString//截取字符串,从哪儿开始,截取到什么地方(区别于截取多少个)${"www.it315.org",4,9}结果是"it315",4后开始,包含9

Fn:substringAfter("www.it315.org",".")//"it315.org"

Fu:substirngBefore

Fn:escapeXml("<a href=''>点点</a>")//转义

Jstl标签:

如果servlet将产生的数据封装到集合中返回给jsp。则jsp需要迭代集合,然后显示数据。要用到jstl 标签

使用JSTL标签:

1.导入jar包:jstl.jar;standard.jar

2.用taglib指令导入标签库: uri="" standard.jar---meta-inf----c.tld

Prefix="c"

 Jstl+el表达式迭代结合:

<c:forEach var="person" items="${list}">

${person.name}

</c:forEach>

JSTL+EL迭代map结合:

<c:forEach var="me" items="${map}">//memap中的一条记录map.entry

${me.key}=${me.value}

</foreach>

<c:if>//标签,检查条件是否成立,成立则执行标签体:

<c:if test="${user!=null}">

 欢迎你:${user.username}

</c:if>

 案例:注册登陆

 Day10:购物车案例

自定义标签:

用于移除jsp中的java代码

使用方法:写一个类实现TAG接口(java代码可以直接放到doStartTag()中,this.pageContex可以直接拿到 pageContext对象,进而拿到其他8大对象),编写TLD文件(参考tomcat/wapps/web-inf/exagmals/jsp2参考头尾)

应用时配置好TLD后,要先倒入标签库, uriTLD中配置的,prefixTld文件名

自定义标签接口,分传统标签TAG和简单标签simpleTag,传统标签已过时(实现不同功能要实现不同接口,学习成本高),开发推荐使用简单标签

传统标签内容:

-------------------------------------------------------

TAG类:可继承子类TagSupport

方法:

setPageContext().//服务器(jsp翻译后的servlet)会调用此方法,将pageContext对象传过来

getParent()//获得父标签,服务器会把父标签的类传进来

setParent()

doStartTag()

doEndTag()

Release()//释放标签所占用的资源

标签处理器类中的所有方法都是由服务器翻译JSPservlet实例化处理器类对象,

调用setPageContext() 方法,把pageContext()传入;

调用setParent(),传入父标签,没有则传入空对象。

遇到开始标签,执行doStartTag()方法

如果有标签体,执行标签体;

遇到结束标签,执行doEndTag()

标签执行完后,服务器,一般回调release(),释放标签运行占用的资源

接着执行后面的servlet 代码。

自定义标签功能扩展:业务逻辑

1.控制 jsp页面某一部分是否执行:把内容放在标签体中,在处理器类中做逻辑判断,是否输出标签体内容

2.控制整个jsp 页面是否输出:在JSP头上插入一个标签,成立则输出下面的JSP内容。否则不输出

3.控制jsp某部分重复输出:在处理器类中让标签体重复输出

4.修改页面内容:在处理器类中根据逻辑判断变化

控制标签体是否执行:

通过标签处理器类的doStartTag中进行逻辑判断,然后根据需要设置不同的返回EVAL_BODAY_INCLUDE或 SKP_BODY

控制整个JSP是否执行:

jsp头写个标签,通过标签处理器类的doEndTag中进行逻辑判断,然后根据需要设置不同的返回EVAL_PAGE或 SKP_PAGE

控制标签体重复输出:

可以给处理器类定义一个成员变量记录重复次数 

用到Tag的子类IterationTag,也是TagSupport 的父类

IterationTag的方法:doAfterBody()如果返回EVAL_BODY_AGAIN, 标签体重复执行。返回SKIP_BODY则不执行标签体

执行步骤:doStartTag---body  doAfterBody----EVAL_BODY_AGAIN----body--doAterBody,不断重复,直到doAfterBody返回值为SKIP_BODY

修改JSP页面输出内容:用到bodyTag类 方法setBodyContent()  

EVAL_BODY_BUFFERED

处理器类继承实现类BodyTagSupport

写法:在doStartTag中返回EVAL_BODY_BUFFERED ,doEndTagthis.BodyContent 拿到数据,修改后输出。

执行步骤:如果doStartTag()返回EVAL_BODY_BUFFERED,则标签体执行完后的结果数据不会直接输出到浏览器,而是存储到bodyContent对象中,传给服务器,服务器自动调用setBodyContent()方法修改修改结果数据

TAG接口的4个常量:

EVAL_PAGE

SKIP_PAGE

EVAL_BODY_INCLUDE//执行标签体

SKIP_BODY// 不执行标签体

-------------------------------------------------------------

简单标签:

注意:

TLD中的 <body-content>改为scriptless

simpleTag接口,实现类simpleTagSupport

方法:

doTag()//处理标签

SetJspBody()//自动将标签体作为JspFragmentJSP片段)传入

setParent()//自动传入父标签

sertJspContent()//自动调用,传入jspContext对象

getParent();

控制标签体是否执行:

doTag()中,this.getJspBody().invoke(null);执行标签体。不执行,则不iinvoke 即可。

标签体重复执行:

Jf.invoke(null); 放在 for 循环中。

修改标签体:拿到标签体,不输出浏览器,输出到一个容器中。 拿到容器数据,修改后,获得流输出

Jf.invoke(new StringWriter());

控制整个JSP是否执行:写一个头标签,doTag中,抛一个SkipPageException异常即可。

带属性的标签:

步骤:在处理器类中定义变量,添加属性的set方法。并在TLD中描述属性

<attribute>

<name>count</name>

<required>true</required>//是否必须

<rtexprvalue>true</rtexprvalue>//属性能否为表达式

</attribute>

服务器会自动将标签的属性值传给处理器类中的变量

自动将标签中的属性的字符串转为响应的类型(8种基本数据类型)

一个标签,一对<tag>,一个属性,一对<attribute>

案例:

自定义<c:if>标签和<c:if>,<c:otherwise>标签(写一个父标签,父处理器类中定义一个变量记录标签体是否执行过)

自定义迭代标签:迭代出来的数据以var为名,存到pageContext域,执行标签体会自动取出(标签体:this.getJspBody().invoke();

可以迭代任意集合的标签:写一个方法逐个判断 items类型,并将它换算为collection,collection进行迭代即可,数据存到jspContext,执行标签体获得var的值

注意:对象数组可以arrays.asList直接转,基本数据类型则要for循环后,添加到collection(要写8if)

数组迭代优化:Array.getLength(items)//得到数组长度,Array.get(items,int),得到每个元素。适用于对象数组和基本数据类型数组

自定义HTML转义标签:

输出HTML标签源码.参考tomcat---util 中的转义方法

将标签体存到StringWriter,调用方法转义后,输出到浏览器

TLD中标签体得四种类型:

Jsp,scriptless,tagdepended(标签体默认是JSP页面的一部分,这个属性是让标签体只给标签用),empty

防盗链:JSp头写一个标签,通过jspContext 拿到request域中的referer头,判断头的内容。(定义2个属性,复用性好)

标签打包技术:

新建一个JAVA项目,导入servletJSPJAR包(tomcat---lib)处理器类拷贝到src,项目下新建一个目录META-INF,TLD文件拷贝到META-INF中,项目右键菜单export导出成jar文件。

使用:导入jar文件,导入标签库,在JSP中使用标签

把项目达成exe文件:先打成 jar,然后变可执行jar(参考tomcat启动JAR文件中的meta-inf中的属性文件的main-class属性),通过exe4j变为exe文件

步骤:

打开jar文件META-INF文件夹,修改属性文件,修改Main-class属性为当前项目的主类完整类名。冒号后要加个空格。

打开lib中的exe4j.exe ,生成exe文件。(可配置图标和启动界面)

Exe运行需要JDK

SUN公司标签库:

可参考jar文件总的TLDstantard.jar

核心标签库:c.tld(必学)

国际化标签库fmt.tld(必学)

数据库标签库sql.tld

XML标签x.tld

JSTL函数(EL函数)fn.tld(必学)

核心标签库:

 <c:out>输出文本到浏览器

应用:转义

<c:out value="<a href="">点点</a>" escapeXml="true"/>

<c:out value="${aaaa}" escapeXml="true" default="xxx"/>//找不到时输出缺省值

<c:set>将某个对象存到域,MAP集合, javabean

<c:set var="name" value="xxxxx" scope="request"/>

<c:set property="name" value="zzzz" target="${map}"/>

<c:set property="name" vlaue="hhh" target="${user}">

<c:remove> 移除4大域中的属性

<c:remove var="name" scope="request">

<c:catch>捕获标签体中抛出的异常

<c:catch var="mvex" scope="page">

<%

10/0

%>

</c:catch>

<c:if var="name" test="${sessionScope.user==null}" scope="page">//判断条件是否成立

xxxxxxxx

</c:if>

<c:choose>用于指定多个条件的组合边界,必须与<c:when><c:otherwise>一起使用,效果类似if--else

<c:choose>

<c:when test=${cunt==0}>

对不起,没有符合要求的记录

</c:when>

<c:otherwise>

符合要求的记录有${count}

</c:otherwise>

</c:choose>

<c:forEach var="e" items="${list}" varStatus="status"/>

varStatus用于定义一个变量记录迭代信息。${status.count}可以获得迭代次数

Var是集合中的元素名

<c:forEach var="num" begin="0" end="${fn:length(list)}">

${list[num]}

</c:forEach >

Var是开始和结束数字变量名

可用于分页

<c:param name="" value=""/>和其他标签合用

<c:url value="/5.jsp" var="url" scope="page"/>

<a href="${url}">点点</a>

 Url 地址重写

<c:redirect url="/4.jsp"/>

<c:redirct url="/4.jsp" context="day11"/>如果需要重定向到其他工程,可指定context

String ab="a,b,c,d";

<c:forTokens var="c" items="string" delims=",">

${c}

</c:forTokens>

字符分割,然后迭代字符串

WEB开发国际化:

国际化internationalization,也称i18n

合格的国际化软件:固定元素和动态数据都国际化

固定文本元素国际化:

将固定文本根据不同语言写到不同的properties文件中。这一组properties文件称为一个资源包。

javaApi 中的 ResourceBundle类用于描述资源包,getBundle可根据来访者的国家自动获取与之对应的资源包文件予以显示

创建资源包和资源文件:

统一个资源包中的资源文件的基名相同,每个资源包有一个默认的资源文件(默认的不带地区标识符)所有资源文件中属性名都一样

资源文件中不能保存中文,要进行编码,使用JDK中的nativ2ascii工具编码后,将码拷贝到资源文件中

基名_语言代码.properties

 Myproperties_zh.properties;myproperties_en.properties;

Myproperties.properties(默认没有对应的具体资源文件时,使用默认资源文件

常看语言和国家代码:

IE--------Internet选项----常规----语言---添加

[ar-QA]前面2个小写字母是语言代码,后面2个字母是国家代码

编码:

ResourceBundle bundle=ResourceBundle.getBundle("cn.itcast.resource.MyResource",Local.ENGLISH);

String username=bundle.getString("username");

获取特定国家资源属性,家Local参数,默认资源属性则不用加。

自动获取国家信息request.getLocal()

动态数据国际化: Local 

数值,货币,时间,日期

日期国际化:DateFormat

 可按国家格式输出日期并控制样式

样式控制:SHORT MEDIUM LONG FULL

 获取DateFormat 实例9种方式:

getDateInstance(int,locale) 只处理日期部分

 getTimeInstance(int,locale)只处理时间部分

 getDateTimeInstance(int,intlocale)同时处理日期时间,参数分别是日期样式,时间样式

例子:Date d=new Date();

DateFormat df=DateFormat.getDateInstance(DateFormat.MEDIUM,Locale.CHIESE);

String result=df.format(d);

  字符串变日期:

DateFormatparse 方法。样式要和字符串显示的样式一致。

数字国际化:NumberFormat

 getCurrencyInstance(locale)获取处理指定国家货币的实例

回返回对应货币符号的字符串

 Int price=56;

NumberFormat nf=NumberFormat.getCurrencyInstance(Local.CHINA);

String p=nf.format(price);//56

将带货币符号的字符串转成数字:parse方法,返回Number类型,调用intValue()等方法可转为 int,double等。

getNumberInstance(locale),getIntergerInstance(),

getPercentInstance(locale)3个方法没有实际意义。

 练习:PPT

多个动态数据的批量国际化:MessageFormat(动态文本国际化)

怎样批量国际化?

将文本中需要国际化得数据用占位符替换(须指定类型样式等)。MessageFormat在输出文本时,可以接受一个参数数组替换文本中的占位符

String p="On {0,time,short},a hurricance destoryed {0,date}";

MessageFormat mf=new MessageFormate(p,Local.CHINA);// 参数(要国际化的文本,国家)

Object params[]={new Date(),99};

String res=mf.format(params); //会返回国际化后的文本(先替换,然后格式化输出)

资源文件的国际化:

String message=ResourceBundle.getBundle("cn.beijing.hd.MyProperties",Local.CHINA).getString("mesage");

Object params={};

MessageFormat mf=new MessageFormate(p,Local.CHINA);

String m=mf.format(params);

HttpUrlConnection类:

模拟浏览器向服务器发请求,并解析响应,显示给浏览器。

拿到HttpUrlConnection,通过将URLopeenConnection()返回的URLConnction转为HttpUrlConnction

 HttpUrlConnectiongetInputStream获得数据流

 getResponseCode()

getHeaderField()

getOutputStream()//setDoOutput(true);

0 0