public
?
class
?ValidatorPlugIn
????
implements
?PlugIn

{

.

????
public
?String?getPathnames()

????
{
????????
return
?pathnames;
????}
????
public
?
void
?setPathnames(String?pathnames)

????
{
????????
this
.pathnames?
=
?pathnames;
????}
????
public
?
void
?init(ActionServlet?servlet,?ModuleConfig?config)
????????
throws
?ServletException

????
{
????????
this
.config?
=
?config;
????????
this
.servlet?
=
?servlet;
????????
try
????????
{
????????????initResources();
????????
catch
(Exception?e)

????????
{
????????????log.error(e.getMessage(),?e);
????????????
throw
?
new
?UnavailableException(
"
Cannot?load?a?validator?resource?from?'
"
?
+
?pathnames?
+
?
"
'
"
);
????????}
????}
????
protected
?
void
?initResources()
????????
throws
?IOException,?ServletException

????
{
????????
if
(pathnames?
==
?
null
?
||
?pathnames.length()?
<=
?
0
)
????????????
return
;
????????StringTokenizer?st?
=
?
new
?StringTokenizer(pathnames,?
"
,
"
);
????????List?streamList?
=
?
new
?ArrayList();
????????
try
????????
{
????????????
while
(st.hasMoreTokens())?

????????????
{
????????????????String?validatorRules?
=
?st.nextToken().trim();
????????????????
if
(log.isInfoEnabled())




.

}
學(xué)習(xí)Java Web 技術(shù),首先必須先把Servlet搞明白。沒(méi)有Servlet基礎(chǔ),別的都是扯淡!
主要就是掌握Servlet的生命周期,所關(guān)聯(lián)到的類,以及他們的方法。
我簡(jiǎn)要回顧一下
打開(kāi)Servlet-API
Servlet接口,三個(gè)關(guān)乎生命周期的重要方法簽名
??????????????????ServletConfig,是一個(gè)較重要的對(duì)象。
??????????????????????????????????????????功能:1,獲得初始化參數(shù)
???????????????????????????????????????????????????2,獲得Servlet上下文對(duì)象。public ServletContextgetServletContext()
GeneralServlet抽象類,等待你去重寫(xiě)service方法。
??????????????????功能主要就是,為程序員編寫(xiě)Servlet提供一些方便
??????????????????????????????????????????方便:1,直接覆蓋public void init() throws ServletException?
???????????????????????????????????????????????????2,直接調(diào)用getInitParameter(java.lang.String?name)?
?????????????????????????????????????????????????????????直接調(diào)用public ServletContextgetServletContext()
?????????????????????????????????????????????????????????直接調(diào)用public void log(java.lang.String?msg)
?????????????????????????????????????????????????????????因?yàn)镚eneralServlet是個(gè)懶家伙,都委托給相應(yīng)ServletConfig/ServletContext完成功能
HttpServlet沒(méi)什么,自己看API吧
ServletRequest能做什么,幾件事
?????????????????????????????????????????????事情1: public java.lang.Object getAttribute(java.lang.String?name)/////還有set
?????????????????????????????????????????????事情2: public java.lang.String getParameter(java.lang.String?name)
????????????????????????????????????????????????????????????????????????????????????????兩方面參數(shù),
??????????????????????????????????????????????????????????????????????????????????????????????????????方面1:html表單中,有name屬性的值.
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????eg. <input type="text" name="userid" size="20" maxlength="20" />
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????request.getParameter("userid");
??????????????????????????????????????????????????????????????????????????????????????????????????????方面2:地址欄參數(shù),eg. http://www.infogo.com.cn/action.do?name=admin
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????request.getParameter("name");
???????????????????????????????????????????????????????????
??????????????????????????????????????????????????????????由于參數(shù)的值有時(shí)會(huì)是一組,那么就要用public java.lang.String[] getParameterValues(java.lang.String?name)
?eg.
???====================================================
?? <c:forEach items="${cart.cartItem}" var="item">
? <TR align=middle>
??? <TD height=30><INPUT type=checkbox value="${item.value.product.id}" name=item></TD>
??? <TD height=30>${item.value.product.name} </TD>
??? <TD height=30>${item.value.product.price} </TD>
??? <TD height=30><INPUT maxLength=10 size=10 value="${item.value.number}" name=itemnum></TD>
??? <TD height=30>${item.value.cost} </TD>
? </TR>
? </c:forEach>
????====================================================
//獲得頁(yè)面,checkbox組的信息,可以知道用戶選擇的商品
??String[] itemkeystr = request.getParameterValues("item");
??System.out.println(itemkeystr);
??????????????? Integer[] itemkeyigr = new Integer[itemkeystr.length];
??????????????? for(int i = 0; i < itemkeystr.length; i++)
??????????????? {
??????????????????????? itemkeyigr[i] = Integer.valueOf(itemkeystr[i]);
??????????????? }
================================================
??????????????????????????????????????????????????????????????????????????????????事情3:public RequestDispatchergetRequestDispatcher(java.lang.String?path)
????????????????????????????????????????????????????????????????????????????????? 事情4:public void setCharacterEncoding(java.lang.String?env)
????????????????????????? throws java.io.UnsupportedEncodingException
eg.主要防止用戶在表單中輸入了中文。
過(guò)濾器實(shí)例:
public
?
final
?
class
?CharacterEncodingFilter?
implements
?Filter

{
????
private
?String??encoding?
=
?
"
gb2312
"
;

????
private
?
boolean
?ignore???
=
?
false
;

????
public
?
void
?init(FilterConfig?config)

????
{
????????
if
?(config.getInitParameter(
"
encoding
"
)?
!=
?
null
)

????????
{
????????????encoding?
=
?config.getInitParameter(
"
encoding
"
);
????????}
????????
if
?(config.getInitParameter(
"
ignore
"
)?
!=
?
null
)

????????
{
????????????ignore?
=
?
new
?Boolean(config.getInitParameter(
"
ignore
"
)).booleanValue();
????????}
????}
????
public
?
void
?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?
throws
?IOException,
????????????ServletException

????
{
????????HttpServletRequest?req?
=
?(HttpServletRequest)?request;
????????HttpServletResponse?res?
=
?(HttpServletResponse)?response;

????????
if
?(
!
ignore)

????????
{
????????????req.setCharacterEncoding(encoding);
????????????res.setCharacterEncoding(encoding);
????????}
????????chain.doFilter(request,?response);
????}
????
public
?
void
?destroy()

????
{

????}
}
ServletResponse,就是負(fù)責(zé)輸出唄。
??????????????????????????????????????????????????????????????????????????????負(fù)責(zé)1:??public void setContentType(java.lang.String?type)?
????????????????????????????????????????????????????????????????????????????????????????????eg.?response.setContentType(text/html;charse=gbk)
??????????????????????????????????????????????????????????????????????????????負(fù)責(zé)2:? public java.io.PrintWriter getWriter() throws java.io.IOException
??????????????????????????????????????????????????????????????????????????????這里注意:
????????????????????????????????????????????????????????????????????????????1必須先設(shè)置setContextType或者setCharacterEncoding,再獲得輸出。否則設(shè)置編碼無(wú)效!
????????????????????????????????????????????????????????????????????????????2不得在ResquestDispatcher.forward()調(diào)用前,進(jìn)行向客戶端的輸出。有風(fēng)險(xiǎn)。
??????????????????????????????????????????????????????????????????????????????
ServletContext整個(gè)應(yīng)用只有一個(gè)實(shí)例,可以為應(yīng)用放置一些只讀的共享數(shù)據(jù)。
責(zé)任1:public java.lang.String getInitParameter(java.lang.String?name)
責(zé)任2:public RequestDispatchergetRequestDispatcher(java.lang.String?path)絕對(duì)路徑
責(zé)任3:public void log(java.lang.String?msg)
Filter接口,實(shí)現(xiàn)對(duì)于某一個(gè)url匹配的過(guò)濾。是一個(gè)責(zé)任鏈模式的應(yīng)用
package
?ljl.shop.common;

import
?java.io.IOException;
???????????????????????????????????????????????????????????????????????????????????????????????????????????????
import
?javax.servlet.Filter;
import
?javax.servlet.FilterChain;
import
?javax.servlet.FilterConfig;
import
?javax.servlet.ServletException;
import
?javax.servlet.ServletRequest;
import
?javax.servlet.ServletResponse;
import
?javax.servlet.http.HttpServletRequest;
import
?javax.servlet.http.HttpServletResponse;



/**?*/
/**
?*?權(quán)限過(guò)濾器?通過(guò)配置web.xml中的filter初始化參數(shù),實(shí)現(xiàn)動(dòng)態(tài)判別
?*?
?*??<filter-mapping>
?*???????<filter-name>CharacterEncodingFilter</filter-name>
?*???????<url-pattern>/*</url-pattern>
?*???</filter-mapping>????????????????????????????????????????????????????????????????????????????
?*
?*???<filter>
?*???????<filter-name>PermissionFilter</filter-name>
?*???????<filter-class>ljl.shop.common.PermissionFilter</filter-class>
?*???????<init-param>
?*???????????????<param-name>checkpage</param-name>
?*???????????????<param-value>checkout.jsp#order_created.jsp#postLogin.jsp</param-value>
?*???????</init-param>
?*???</filter>
?*?
?*?
@author
?lujl
?
*/
public
?
class
?PermissionFilter?
implements
?Filter

{
????
private
?String?checkpage?
=
?
null
;

????
private
?FilterConfig?config?
=
?
null
;

????
public
?
void
?init(FilterConfig?config)

????
{
????????System.out.println(config.getInitParameter(
"
checkpage
"
));
????????
if
(config.getInitParameter(
"
checkpage
"
)?
!=
?
null
)

????????
{
????????????System.out.println(config.getInitParameter(
"
checkpage
"
));
????????????
//
vip.jsp#checkout.jsp#
????????????checkpage?
=
?config.getInitParameter(
"
checkpage
"
);????????????
????????}
????????
this
.config?
=
?config;
????}
????
public
?
void
?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?
throws
?IOException,ServletException

????
{
????????HttpServletRequest?hrequest?
=
?(HttpServletRequest)request;
????????String?path?
=
?hrequest.getServletPath();
????????String[]?pages?
=
?checkpage.split(
"
#
"
);
????????System.out.println(pages.length);
????????
for
(
int
?i?
=
?
0
;?i?
<
?pages.length;?i
++
)

????????
{
????????????
if
(path.indexOf(pages[i])?
!=
?
-
1
)
//
解析的path包含這些頁(yè)面,那么就檢查是否登錄
????????????
{
????????????????
if
(hrequest.getSession().getAttribute(
"
user
"
)?
!=
?
null
)

????????????????
{
????????????????????chain.doFilter(request,?response);
????????????????????
return
;
????????????????}
????????????????
else
????????????????
{
????????????????????
this
.config.getServletContext().getRequestDispatcher(
"
/login.jsp
"
).forward(request,response);
????????????????????
return
;
????????????????}
????????????}
????????????
????????}
????????chain.doFilter(request,response);????
????}
????
public
?
void
?destroy()

????????
{
???????????????????????????????????????????????????????????????????????????????????????????????????????????????
????????}
}
===========================================================================?????
HttpServletRequest
還有一些Http協(xié)議的特征方法
public Cookie[] getCookies()
public java.lang.String getPathInfo()???????????????? http://www.infogo.com.cn/webapp/servlet/aaa
?????????????????????????????????????????????????????????????????????????????????如果url-pattern是/servlet/*???????? 那么request.getPathInfo() 返回 /aaa
public java.lang.String getContextPath()?????????
?????????????????????????????????????????????????????????????????????????????????/webapp
???????????????????????????????????????????????????????????????????????????????? jsp el??也可以取到此值??? ${pageContext.request.contextPath}
?????????????????????????????????????????????????????????????????????????????????也就是<%=request.getContextPath()%>
public java.lang.String getQueryString()
???????????????????????????????????????????????????????????????????????????????? 只拿到地址欄參數(shù)字符串,自己解析吧:)
public java.lang.String getServletPath()
?????????????????????????????????????????????????????????????????????????????????/servlet
public HttpSessiongetSession(boolean?create)
?????????????????????????????????????????????????????????????????????????????????傳入true,如果有,直接返回,沒(méi)有創(chuàng)建??????? 等同于getSession()無(wú)參
?????????????????????????????????????????????????????????????????????????????????傳入false,沒(méi)有則返回null
request.getRequestURI()???????????????????? /WebTest/servlet/MethodServlet
request.getRequestURL()??????????????????? http://localhost:8080/WebTest/servlet/MethodServlet?
URI是一個(gè)相對(duì)的位置,或者說(shuō)就是一個(gè)標(biāo)識(shí),URL是資源定位,所以很精確。
HttpServletResponse
public void addCookie(Cookie?cookie)
public java.lang.String encodeURL(java.lang.String?url)???????? URL回寫(xiě)機(jī)制,說(shuō)白了就是把jsessionid放在連接里,下回請(qǐng)求時(shí)就能穿回來(lái)了,不在需要Cookie了。注意,如果瀏覽器支持Cookie,無(wú)效果!!!
public java.lang.String encodeRedirectURL(java.lang.String?url)????? 用于response.sendRedirect()函數(shù)中。
最后一招:
public void sendError(int?sc)? throws java.io.IOException??
把API上面的靜態(tài)常量往里放!
+++++++++++++++++++++++
public boolean isRequestedSessionIdValid()?? 待使用
+++++++++++++++++++++++
--------------------------------------------------------------
HttpSessionListener
public void sessionCreated(HttpSessionEvent?se)
做JSP開(kāi)發(fā)時(shí),由于Session是在用戶訪問(wèn)jsp時(shí),自動(dòng)創(chuàng)建的。如果能在用戶一訪問(wèn)就往Session中放入一個(gè)容器對(duì)象呢,而不是在用戶發(fā)出某一個(gè)特定Action請(qǐng)求時(shí),再判斷,再setAttribute();
那么就用Listener吧,這時(shí)使用是一個(gè)完全充分的理由。[還有ServletContextListener]
public void sessionDestroyed(HttpSessionEvent?se)???基本可以統(tǒng)計(jì)用戶在線時(shí)間。
或者做考試系統(tǒng)時(shí),會(huì)使用到。
====================================
HttpSessionAttributeListener監(jiān)聽(tīng)Session
HttpSessionBindingListener監(jiān)聽(tīng)被session的setAttribute方法加入的對(duì)象。
實(shí)現(xiàn)接口的類型不同!!注意區(qū)分。
====================================
HttpServletResponseWrapper
是個(gè)適配器。
在制作一個(gè)filter的時(shí)候,如果想在原有的輸出,某部分,添加一部分內(nèi)容,必須對(duì)HttpServletResponse進(jìn)行適配。
MyResponse myRes = new?MyResponse(response);
chain.doFilter(request,myRes);
String contents = myRes.toString();
//解析字符串,比如尋找</body>
myRes.getResponse().getWriter();//取回原來(lái)的response????????? ServletResponseWrapper有個(gè)有參的構(gòu)造方法。
//真正輸出
public class MyResponse extends HttpServletResponseWrapper
{
??????
??????MyResponse(ServletResponse res)
??????{
????????????super(res);
??????}
??????public PrintWriter getWriter()
??????{
????????????return new PrintWriter(caw);
??????}
??????
??????private CharArrayWriter caw = new CharArrayWriter();//IO 我就不廢話了,也就是一個(gè)內(nèi)存中的字符輸出流。
??????public String toString()
??????{
????????????return caw.toString();
??????}
}
================================================================================
?HttpSession接口
public void setMaxInactiveInterval(int?interval)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
public void invalidate()
public boolean isNew(),就是創(chuàng)建后,還沒(méi)讓客戶端知道呢!
-----------------------------
JSP
就是一個(gè)Servlet
<%
??????!
%>??
定義那個(gè)Servlet的成員
?<%!class ABC{}%>定一個(gè)類都沒(méi)有問(wèn)題!
表達(dá)式
<%=request.getParameter("user")%>?????????????????????
代碼段
<%
%>
指令
<% @page errorPage="relativeURL"%>
<% @page isErrorPage="true"%>
<% @page contextType="text/html;charset=gb2312" %>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
動(dòng)作
http://java.sun.com/products/jsp/syntax/2.0/syntaxref20.html
<jsp:include page="scripts/login.jsp">
???<jsp:param name="username" value="jsmith" />
</jsp:include>
<jsp:forward page="/servlet/login">
???<jsp:param name="username" value="jsmith" />
</jsp:forward>
================
<tt:screen id="/bookcatalog">
???<tt:parameter name="title" direct="true">
??????<jsp:attribute name="value" >
?????????<fmt:message key="TitleBookCatalog"/>
??????</jsp:attribute>
???</tt:parameter>
...
</tt:screen>
注意,也就是<tt:parameter這個(gè)標(biāo)簽,還有一個(gè)屬性就是value,那么它的值是通過(guò)變化取得。
jsp先回把html,翻譯成為xml的標(biāo)準(zhǔn)試圖,再使用一個(gè)引擎翻譯成為java代碼。
<jsp:element name="h1">
???<jsp:attribute name="align">
??????center
???</jsp:attribute>
???<jsp:body>
??????This is the header!
???</jsp:body>
</jsp:element>
您把這段代碼放入jsp,可以通過(guò)的。
<h1 align="center">
?????? This is the header!
</h1>????????????????????
<%
Person p = null;
synchronized(application){
???p = (Person)application.getAttribute("person");
???if(p==null)
???{
?????????p = new Person();
?????????application.setAttribute("person",p);???
???}
}
%>
通用一些
Class.forName("com.infogo.bean.Person").newInstance();
<jsp:useBean id="p" class="com.infogo.bean.Person" scope="application" />? scope默認(rèn)為page
這就是useBean指令做的事情。
<jsp:useBean id="persons" type="java.util.Collection" scope="request" />
注意type就是只說(shuō)明它是什么類型的,不做實(shí)例化的步驟
MVC中的視圖,就是使用集合bean的。如果不存在,會(huì)拋異常。bean persons not found within scope
<jsp:getProperty name="p" property="name" />
Stores all of the values of request parameters in bean properties. The names of the bean properties must match the names of the request parameters. A bean property is usually defined by a variable declaration with matching getter and setter methods (for more information, see http://java.sun.com/products/javabeans/docs/).
<jsp:setProperty name="mybean" property="*" />
<jsp:setProperty name="mybean" property="username" />
<jsp:setProperty name="mybean" property="username" value="Steve" />
====================================
先來(lái)說(shuō)說(shuō),JSTL和EL的東西
Sun專門定制了一組標(biāo)簽庫(kù)來(lái)完成頁(yè)面的程序流程控制,避免了代碼片斷的出現(xiàn)。而EL則避免了頁(yè)面出現(xiàn)表達(dá)式,而且對(duì)于attribute中的數(shù)據(jù)的非空驗(yàn)證是自動(dòng)完成。如果為空,只會(huì)出現(xiàn)沒(méi)有輸出內(nèi)容。
EL還是比較簡(jiǎn)單的。
http://java.sun.com/products/jsp/syntax/2.0/syntaxref207.html#1010522
上面是sun的教程。
=====================================
在說(shuō)標(biāo)簽和EL原理之前,必須把JSP的原理搞清楚。
客戶端請(qǐng)求jsp,由一個(gè)翻譯引擎對(duì)jsp進(jìn)行java代碼的翻譯,然后由容器進(jìn)行編譯,加載到容器,invoke Servlet。
一個(gè)jsp
<%
@?page?language
=
"
java
"
?import
=
"
java.util.*
"
?pageEncoding
=
"
UTF-8
"
%>
<%
@?page?info
=
"
view?jsp?translate
"
%>
<!
DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"
>
<
html
>
??
<
head
>
????
????
<
title
>
View?Jsp?Translation
</
title
>
????
????
<
meta?
http-equiv
="pragma"
?content
="no-cache"
>
????
<
meta?
http-equiv
="cache-control"
?content
="no-cache"
>
????
<
meta?
http-equiv
="expires"
?content
="0"
>
????
<
meta?
http-equiv
="keywords"
?content
="keyword1,keyword2,keyword3"
>
????
<
meta?
http-equiv
="description"
?content
="This?is?my?page"
>
????
??
</
head
>
??
??
<
body
>
????This?is?my?JSP?page.?
<
br
>
??
</
body
>
</
html
>
對(duì)應(yīng)代碼
package?org.apache.jsp;

import?javax.servlet.*;
import?javax.servlet.http.*;
import?javax.servlet.jsp.*;
import?java.util.*;

public?final?class?ViewJspTranslate_jsp?extends?org.apache.jasper.runtime.HttpJspBase
????implements?org.apache.jasper.runtime.JspSourceDependent?{

//這就是page指令生成的
??public?String?getServletInfo()?{
????return?"view?jsp?translate";
??}

??private?static?java.util.Vector?_jspx_dependants;

??public?java.util.List?getDependants()?{
????return?_jspx_dependants;
??}

??public?void?_jspService(HttpServletRequest?request,?HttpServletResponse?response)
????????throws?java.io.IOException,?ServletException?{

//內(nèi)置對(duì)象
????JspFactory?_jspxFactory?=?null;
????PageContext?pageContext?=?null;
//使用page 指令中 Session=false,就不會(huì)出現(xiàn)session變量了,提高一些效率,注意只是不出現(xiàn)該引用。一訪問(wèn)jsp/Session就創(chuàng)建了。只能通過(guò)SessionListener進(jìn)行創(chuàng)建時(shí)的截獲,放置一些初始對(duì)象。
????HttpSession?session?=?null;
????ServletContext?application?=?null;
????ServletConfig?config?=?null;
????JspWriter?out?=?null;
????Object?page?=?this;
????JspWriter?_jspx_out?=?null;
//關(guān)鍵的JSP上下文對(duì)象
????PageContext?_jspx_page_context?=?null;


????try?{
??????_jspxFactory?=?JspFactory.getDefaultFactory();
??????response.setContentType("text/html;charset=UTF-8");
??????pageContext?=?_jspxFactory.getPageContext(this,?request,?response,
??????????????????null,?true,?8192,?true);
??????_jspx_page_context?=?pageContext;
??????application?=?pageContext.getServletContext();
??????config?=?pageContext.getServletConfig();
??????session?=?pageContext.getSession();
??????out?=?pageContext.getOut();
??????_jspx_out?=?out;

??????out.write("\r\n");
??????out.write("\r\n");
??????out.write("<!DOCTYPE?HTML?PUBLIC?\"-//W3C//DTD?HTML?4.01?Transitional//EN\">\r\n");
??????out.write("<html>\r\n");
??????out.write("??<head>\r\n");
??????out.write("????\r\n");
??????out.write("????<title>View?Jsp?Translation</title>\r\n");
??????out.write("????\r\n");
??????out.write("????<meta?http-equiv=\"pragma\"?content=\"no-cache\">\r\n");
??????out.write("????<meta?http-equiv=\"cache-control\"?content=\"no-cache\">\r\n");
??????out.write("????<meta?http-equiv=\"expires\"?content=\"0\">\r\n");
??????out.write("????<meta?http-equiv=\"keywords\"?content=\"keyword1,keyword2,keyword3\">\r\n");
??????out.write("????<meta?http-equiv=\"description\"?content=\"This?is?my?page\">\r\n");
??????out.write("????\r\n");
??????out.write("??</head>\r\n");
??????out.write("??\r\n");
??????out.write("??<body>\r\n");
??????out.write("????This?is?my?JSP?page.?<br>\r\n");
??????out.write("??</body>\r\n");
??????out.write("</html>\r\n");
????}?catch?(Throwable?t)?{
??????if?(!(t?instanceof?SkipPageException)){
????????out?=?_jspx_out;
????????if?(out?!=?null?&&?out.getBufferSize()?!=?0)
??????????out.clearBuffer();
????????if?(_jspx_page_context?!=?null)?_jspx_page_context.handlePageException(t);
??????}
????}?finally?{
??????if?(_jspxFactory?!=?null)?_jspxFactory.releasePageContext(_jspx_page_context);
????}
??}
}

所以如果發(fā)生編譯不過(guò),就到tomcat的work目錄里看看java代碼,比較容易看到錯(cuò)誤。jsp的提示對(duì)于嚴(yán)重的語(yǔ)法錯(cuò)誤是不太友好的。
對(duì)于隱含對(duì)象,就可以直接使用了。
<%=request.getContextPath()%>
<%=request.getInitParameter("user")%>
對(duì)于JSP也可以配置初始化參數(shù)。
web.xml對(duì)于JSP進(jìn)行部署
<servlet>
???<servlet-name>some name</servlet-name>
???<jsp-file>/internal/config.jsp</jsp-file>
</servlet>
<servlet-mapping>
???<servlet-name>some name</servlet-name>
???<url-pattern>/internal/config.jsp</url-pattern>
</servlet-mapping>
url-pattern如果配置與jsp路徑不一樣,那么只有從這個(gè)pattern訪問(wèn)的jsp才能獲得初始化參數(shù)。直接訪問(wèn)jsp的沒(méi)有。
=========================
繼續(xù)使用PageContext,可以得到很多信息。

<%
@?page?language="java"?pageEncoding="UTF-8"%>

<%
@?page?info="view?jsp?translate"%>
<jsp:useBean?id="client"?class="com.bean.SthBizBean"?scope="page">
????<jsp:setProperty?name="client"?property="currentPage"?value="<%=pageContext%>"/>
</jsp:useBean>
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">
<html>
??<head>
????
????<title>View?Jsp?Translation</title>
????
????<meta?http-equiv="pragma"?content="no-cache">
????<meta?http-equiv="cache-control"?content="no-cache">
????<meta?http-equiv="expires"?content="0">
????<meta?http-equiv="keywords"?content="keyword1,keyword2,keyword3">
????<meta?http-equiv="description"?content="This?is?my?page">
????
??</head>
??
??<body>
????Client?Info:<jsp:getProperty?name="client"?property="clientInfo"?/>
??</body>
</html>?
package?com.bean;

import?javax.servlet.ServletRequest;
import?javax.servlet.jsp.PageContext;


public?class?SthBizBean?
{

????PageContext?pctx?=?null;


????public?void?setCurrentPage(PageContext?pctx)?
{
????????this.pctx?=?pctx;
????}


????public?String?getClientInfo()?
{
????????StringBuffer?buf?=?new?StringBuffer();
????????ServletRequest?request?=?pctx.getRequest();
????????buf.append("<br>協(xié)議:"?+?request.getProtocol()?+?"<br>").append(
????????????????"地址:"?+?request.getRemoteAddr()?+?"<br>").append(
????????????????"端口:"?+?request.getRemotePort());
????????return?buf.toString();
????}

}

==========================
java.lang.Object
?
javax.servlet.jsp.JspContext
?????
javax.servlet.jsp.PageContext
去查看一下PageContext這個(gè)父類型。
public abstract java.lang.Object findAttribute(java.lang.String?name)
- Searches for the named attribute in page, request, session (if valid), and application scope(s) in order and returns the value associated or null.
看好這個(gè)方法是試圖從四個(gè)范圍內(nèi)取值,如果都取不到,就會(huì)返回null。
public abstract void removeAttribute(java.lang.String?name)
去除所有的屬性值。
可以單獨(dú)設(shè)置,作用范圍
public abstract void removeAttribute(java.lang.String?name,
???????????????????????????????????? int?scope)
就是用子類PageContext設(shè)置的常量。
============================================================
可以自己寫(xiě)自定義標(biāo)簽完成復(fù)雜的頁(yè)面表現(xiàn)功能。
直接使用JSTL就行了。
=======================
JSTL配置EL,就可以使得JSP開(kāi)發(fā)人員與JavaBean業(yè)務(wù)實(shí)現(xiàn)人員完全獨(dú)立工作。測(cè)試也可以獨(dú)立進(jìn)行。
因?yàn)槭褂肊L語(yǔ)言,不再需要<jsp:useBean>指令來(lái)設(shè)置一個(gè)JavaBean的對(duì)象到某一個(gè)范圍內(nèi),并設(shè)置一個(gè)變量。
使用EL,直接可以使用Attribute了。
${user.name}
等價(jià)于
判斷是否為空
<%=user.getName()%>
而且不需要判斷user是否為空。
---------
EL有很多內(nèi)嵌對(duì)象,當(dāng)然只限制于在EL表達(dá)式中使用。
${pageContext.request.contextPath}
看到按照J(rèn)AVABEAN命名的好處了吧,都可以按照標(biāo)準(zhǔn)命名去取值的。多方便。
參數(shù)
<c:if test=""${!empty param.username}">
??????do sth
</c:if>
訪問(wèn)javabean
${bean1.a.c}
相當(dāng)于
<%=bean1.getA().getC()%>
注意getA()方法本身就是返回一個(gè)javabean對(duì)象,所以可以繼續(xù)javabean訪問(wèn)。
對(duì)于集合對(duì)象,Map對(duì)象。
訪問(wèn)可以通過(guò)另外的方式訪問(wèn)。

<%
@?page?language="java"?import="java.util.*"?pageEncoding="UTF-8"%>

<%
@?page?import="com.bean.UserBean"%>

<%
String?path?=?request.getContextPath();
String?basePath?=?request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

Map?userMap?=?new?HashMap();
UserBean?user_a?=?new?UserBean();
user_a.setName("ljl");
user_a.setAddress("bj");
UserBean?user_b?=?new?UserBean();
user_b.setName("superman");
user_b.setAddress("Mars");

userMap.put("ua",user_a);
userMap.put("ub",user_b);

request.setAttribute("userMap",userMap);

%>

<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">
<html>
??<head>
????<base?href="<%=basePath%>">
????
????<title>My?JSP?'ViewEL.jsp'?starting?page</title>
????
????<meta?http-equiv="pragma"?content="no-cache">
????<meta?http-equiv="cache-control"?content="no-cache">
????<meta?http-equiv="expires"?content="0">
????<meta?http-equiv="keywords"?content="keyword1,keyword2,keyword3">
????<meta?http-equiv="description"?content="This?is?my?page">
????
????<!--
????<link?rel="stylesheet"?type="text/css"?href="styles.css">
????-->
??</head>
??
??<body>
????This?is?my?JSP?page.?<br>
????
????${"${userMap.ua}"}:?${userMap.ua}
????<br>
????${'${userMap["ua"]}'}:?${userMap["ua"]}
??</body>
</html>

結(jié)果:
This is my JSP page.
${userMap.ua}: com.bean.UserBean@21af3d5
${userMap["ua"]}: com.bean.UserBean@21af3d5
-----------
????????
??? ${userMap["ub"].name}?
??? ${userMap["ub"].address}
直接訪問(wèn)屬性
這只是一種簡(jiǎn)單的情況,有時(shí)做應(yīng)用并不是這樣。
====================
?代碼示例:
? <c:forEach items="${cart.cartItem}" var="item">
? <TR align=middle>
??? <TD height=30><INPUT type=checkbox value="${item.value.product.id}" name=item></TD>
??? <TD height=30>${item.value.product.name} </TD>
??? <TD height=30>${item.value.product.price} </TD>
??? <TD height=30><INPUT maxLength=10 size=10 value="${item.value.number}" name=itemnum></TD>
??? <TD height=30>${item.value.cost} </TD>
? </TR>
? </c:forEach>
以上為一個(gè)購(gòu)物籃的頁(yè)面的部分代碼:
這設(shè)計(jì)時(shí)。Cart類 有一個(gè)HashMap集合保存著選購(gòu)的Item。key為產(chǎn)品Id,而value是頁(yè)面需要展示的東西。
是一個(gè)個(gè)Item對(duì)象。
對(duì)于key為Id,或者頁(yè)面不關(guān)心,甚至根本不知道是什么的HashMap如何遍歷呢?
EL,和JavaBean的完美組合再次讓我理解JavaBean的封裝性的好處。
java.util
Interface Map.Entry<K,V>
A map entry (key-value pair). The Map.entrySet method returns a collection-view of the map, whose elements are of this class.
也就是說(shuō)Map里每一個(gè)元素是一個(gè)一個(gè)的Entry。
再看看Entry方法。
?K | getKey() ??????????Returns the key corresponding to this entry. |
?V | getValue() ??????????Returns the value corresponding to this entry. |
哈哈,javabean規(guī)范!
${item.value.product.name}
就取到了。
==========
JSTL
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSTL.html如果做過(guò)自定義標(biāo)簽的開(kāi)發(fā),就很容易使用了。。
??<c:forEach?items="${cart.cartItem}"?var="item"?varStatus="i">
??<TR?align=middle>

????<TD?height=30>${i.count} </TD><%
--?${i.index}??--%>
????<TD?height=30>${item.value.product.name} </TD>
????<TD?height=30>${item.value.product.price} </TD>
????<TD?height=30>${item.value.number} </TD>
????<TD?height=30>${item.value.cost} </TD>
??</TR>
??</c:forEach>=================
struts真的太簡(jiǎn)單了
ActionServlet委托RequestProcessor完成功能。
ActionForm有幾種??????? DynActionForm的使用和驗(yàn)證kuangjia
????public?ActionErrors?validate(ActionMapping?actionMapping,?HttpServletRequest?httpServletRequest)?

????
{
????????ActionErrors?errors?=?new?ActionErrors();
????????
????????if(name?==?null?||?name.trim().length()?==?0)

????????
{
????????????ActionError?error?=?new?ActionError("errors.name.required");
????????????errors.add("name",?error);
????????}
????????
????????if(password?==?null?||?password.trim().length()?==?0)

????????
{
????????????ActionError?error?=?new?ActionError("errors.password.required");
????????????errors.add("password",?error);
????????}
????????
????????return?errors;
????}頁(yè)面
<html:errors/>
errors.password.required
就是資源文件的內(nèi)容
==============
第二種控制異常的方法
拋異常
struts-config.xml
<action?attribute="addcourseForm"?name="addcourseForm"?parameter="addcourse"?path="/addcourse"?scope="request"?type="exam.java.advanced.action.ExamIssueMappingActionAction">
????????????<exception?key="operate.addcourse"?path="/error.jsp"?type="exam.java.advanced.BusinessException"?/>
????????????<forward?name="success"?path="/success.jsp"?redirect="true"?/>
????????</action>
public?class?ExamIssueMappingActionAction?extends?MappingDispatchAction?
{

????public?ActionForward?addcourse(ActionMapping?mapping,?ActionForm?arg1,
????????????HttpServletRequest?request,?HttpServletResponse?arg3)

????????????throws?Exception?
{
????????EnrollmentBiz?biz?=?new?EnrollmentBiz();

????????try?
{
????????????Course?crs?=?new?Course();
????????????DynaActionForm?f?=?(DynaActionForm)?arg1;
????????????crs.setId((String)?f.get("courseid"));
????????????crs.setName((String)?f.get("name"));
????????????crs.setDescription((String)?f.get("description"));

????????????biz.saveCourse(crs);
????????????return?mapping.findForward("success");

????????}?catch?(Exception?ex)?
{
????????????ex.printStackTrace();
????????????throw?new?BusinessException(ex);
????????}
????}
=============
驗(yàn)證框架
現(xiàn)在struts-config.xml注冊(cè)驗(yàn)證的插件,
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
??<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,
??????????????????????????? /WEB-INF/validation.xml" />
?</plug-in>
org.apache.struts.action
Interface PlugIn
這個(gè)接口就是插件接口,可以自己實(shí)現(xiàn)這個(gè)接口。
按照人家ValidatorPlugIn的方式寫(xiě)一個(gè)屬性,以便在struts-config.xml中描述插件時(shí),提供具體值。
pathnames
??? public String getPathnames()
??? {
??????? return pathnames;
??? }
??? public void setPathnames(String pathnames)
??? {
??????? this.pathnames = pathnames;
??? }
StringTokenizer st = new StringTokenizer(pathnames, ",");
-----------
org.apache.struts.config.ModuleConfig
該對(duì)象在init時(shí)傳入,可以利用來(lái)獲得struts-config.xml這個(gè)文件的信息。
=====================
DispatchAction就是對(duì)于不同form表單在同一Action中處理的解決方案,struts-config.xml在Action標(biāo)記中加一個(gè)parameter屬性method,form的action則用function.do?method=add
LookupDispatchAction就是對(duì)于同一個(gè)頁(yè)面不同的按鈕想都在一個(gè)Action中處理。需要重寫(xiě)一個(gè)getMap方法。
MappingDispatchAction就是每個(gè)方法一個(gè)Action標(biāo)記對(duì)應(yīng)。
最后就是使用令牌的方式來(lái)防止重復(fù)提交。
org.apache.struts.action.Action
這個(gè)父類的方法
protected java.lang.String generateToken(javax.servlet.http.HttpServletRequest?request)
protected boolean isTokenValid(javax.servlet.http.HttpServletRequest?request)
protected void resetToken(javax.servlet.http.HttpServletRequest?request)