chap 8 处理Input/Output |
(1)input问题:用户未按所需格式进行输入,因此在使用input前,必须对其validate,确保它是可用的。 |
(2)output问题:browser对传送给它的html的格式很挑剔,[例如]O'Reilly可能被看成O |
8.1 读取request的参数值 |
(1)<form>元素的action属性:表示一个web server resourse(例如一个jsp页面),该form递交到这个resource |
(2)<form>元素的method属性:告诉browser在提交form时,使用什么http方法。 |
[注]GET方法:用于只retrieve info的request;POST方法:用于造成irreversible的request,例如把form值保存到database。 |
(3)<input>元素的type属性:告诉browser使用哪一种input control来render。[例如]text,radio,checkbox,submit |
(4)发送request:用户点击submit按钮时,browser向action指定的web-server资源发送request(用method指定的方法)。用户输入的所有值,都作为http的request参数。 |
(5)request参数的传送:[1]对于GET request,参数作为附加到url的query string传送;对于POST request,参数在request body中传送。[2]无论传输方法如何,每个参数都用name/value对表示;其中,name是使用name属性对form element赋的值,而value是用户输入的、或value属性指定的。[注]对于checkbox,如果多选,就传送多个name一样、value不同的参数;如果没选,就不传送对应参数。对于<select>元素,一样。 |
8.1.1 通过jstl action访问参数值 |
[例子]Name: <c:out value="${param.userName}" /><br> |
(1)param:是一种implicit的EL变量,包含了所有发送到页面的request parameter的collection(java.util.Map) |
[注]要获得特定变量的值,只需要使用dot符号。 |
[注]<c:out>的属性,参加table 8-1 |
[例子] Favorite Food: <c:forEach items="${paramValues.food}" var="current"> <c:out value="${current}" /> </c:forEach> |
(1)<c:forEach> action:根据属性的指定,多次处理其body。 |
(2)items属性:collection,表示需要遍历(iterate over)的value。 |
(3)var属性:变量名,表示当前element的value |
(4)paramValues变量:每个request parameter被表示为一个值的array。[注]在param中,被表示为一个值。 |
[注]<c:forEach>的属性(例如begin,varStatus等,[参见]table 8-2 |
8.1.2 访问其它request 数据 |
(1)header values:通过header和headerValues变量 |
(2)cookies:通过cookie变量 |
(3)其它request信息,可以通过pageContext变量的request属性。 [注]request属性是javax.servlet.http.HttpServletRequest的一个instance。其属性参加table 8-3 |
[例子] <c:out value="${pageContext.request.method}" /> |
(4)cookie值的访问: |
[方法1]使用cookie变量 |
[方法2]使用request的cookie属性 |
[例子] <c:forEach items="${pageContext.request.cookies}" var="c"> <b><c:out value="${c.name}" /></b>: <c:out value="${c.value}" /><br> </c:forEach> |
[注]cookie对应javax.servlet.http.Cookie[] |
(5)header值的访问: |
[例子] <c:forEach items="${headerValues}" var="h"> <b><c:out value="${h.key}" /></b>: <c:forEach items="${h.value}" var="value"> <br> <c:out value="${value}" /> </c:forEach> <br> </c:forEach> |
8.1.3 使用bean捕获参数值 |
(1)bean用于捕获用户的input:捕获的数据可以被bean自己处理,或作为其它server component的input(该component可把数据存储到db,或选择合适的显示banner)。 |
(2)本书作者写了一个com.ora.jsp.beans.userinfo.UserInfoBean |
[例子] <jsp:useBean id="userInfo" class="com.ora.jsp.beans.userinfo.UserInfoBean"> <jsp:setProperty name="userInfo" property="*" /> </jsp:useBean> …… Name: <c:out value="${userInfo.userName}" /><br> …… |
[注]通过property="*",<jsp:set Property>就把bean的所有属性值设为对应的参数;参数名称必须与属性名称完全一样。 |
8.2 验证用户的input |
(1)三种方法:[1]简单input,用jstl验证;[2]稍复杂的验证规则,用bean实现;[3]如果将jsp结合servlet使用,servlet进行验证,而jsp页面仅当input通过验证后才被invoke;[参见]chap18 |
8.2.1 使用jstl action验证用户的input |
[例子] <%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <html> <head> <title>User Info Entry Form</title> </head> <body bgcolor="white"> <form action="validate_jstl.jsp" method="post"> <input type="hidden" name="submitted" value="true"> <table> <c:if test="${param.submitted && empty param.userName}"> <tr><td></td> <td colspan="2"><font color="red"> Please enter your Name </font></td></tr> </c:if> <tr> <td>Name:</td> <td> <input type="text" name="userName" value="<c:out value="${param.userName}" />"> </td> </tr> |
(1) <input>元素的type是hidden:不显示,但value像正常的parameter一样传递。通过下面EL中的param.submitted,可判断是否需要对输入进行验证。[注意]submitted不是请求load该页面的最初request的一部分,因此不具有值true;提交表单之后,submitted的值变为true。 |
(2) <c:if> action的属性(例如test),[参加]table 8-5 |
(3) empty运算符:用于避免区分null与空string(""),否则就要写(param.userName == null || param.userName == '')}">。也能用于测试大多数常见类型的collection是否为空(例如array,List) |
[例子] <c:if test="${param.submitted && param.gender != 'm' && param.gender != 'f'}"> …… <c:choose> ... <c:when> ... <c:otherwise> … |
(1) <c:choose> action没有属性,只用于将任意数量的<c:when>和一个可选的<c:otherwise>放到一组中。 |
[注]<c:choose>block用于从一组相关的、互斥的选择中,选出一个。<c:choose> action确保仅有第一个test属性为true的<c:when>被处理。 |
(2)为什么要检查checked box? |
初看起来,checked box只可能选择f/m,但实际上,对于http://localhost:8080/ora/ch8/validate_jstl.jsp?submitted=true&gender=x,肯定是需要判断gender数据是错误的(x) |
[例子] <c:forEach items="${paramValues.food}" var="current"> <c:choose> <c:when test="${current == 'z'}"> <c:set var="pizzaSelected" value="true" /> …… |
(1) <c:set> action的var属性:表示值为value的变量的名称。 |
8.2.2 使用bean验证用户input |
(1) jstl只适用于验证简单的输入,但对于复杂的input(例如email地址),最好用bean。因为bean是用java代码实现的,可以访问所有java api,可以做任何一种验证。 |
(2) 本书中,UserInfoBean实现了验证功能。所有属性[参见]Table 8-8;实现[参见]chap19 |
[例子] <jsp:useBean id="userInfo" class="com.ora.jsp.beans.userinfo.UserInfoBean"> <jsp:setProperty name="userInfo" property="*" /> </jsp:useBean> …… <input type="hidden" name="submitted" value="true"> <c:if test="${param.submitted && userInfo.userNameValid == false}"> ...... <input type="text" name="userName" value="<c:out value="${userInfo.userName}" />"> ...... |
(1)使用bean的其它好处:所有的判断逻辑都封装在bean中,而不是页面中;将来修改规则时,只需要修改bean,而不需要修改页面。 |
[例子] <c:if test="${param.submitted && !userInfo.foodValid}"> …… <input type="checkbox" name="food" value="z" <c:if test="${userInfo.pizzaSelected}">checked</c:if>> Pizza<br> …… |
8.3 格式化hutml的output |
(1) 例如,在name栏中输入包含双引号""的字符串,返回的html页面源码中,被"代替。[原因]因为<input>元素的<value>属性就是用双引号包起来的。因此就由html character-entity替代。 |
(2) ',",<,>,& 分别被',",<,>,& |
(3) 这种字符转换可以部分预防cross site scripting attack:否则像<script>window.close( )</script>这种字符串如果填入栏中,就会导致窗口关闭。[详细参见] http://www.cert.org/advisories/CA-2000-02.html |
(4) 极少情况下,特殊字符的转换本身就会带来麻烦。<c:out> action提供了一个escapeXML属性,设为false可禁用转换。但一般不用考虑它带来的麻烦。 |
chap 8 处理Input/Output
最新推荐文章于 2024-06-02 14:12:08 发布