隨筆-159  評論-114  文章-7  trackbacks-0



          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())

          .

          }

          學習Java Web 技術(shù),首先必須先把Servlet搞明白。沒有Servlet基礎(chǔ),別的都是扯淡!

          主要就是掌握Servlet的生命周期,所關(guān)聯(lián)到的類,以及他們的方法。

          我簡要回顧一下

          打開Servlet-API

          Servlet接口,三個關(guān)乎生命周期的重要方法簽名

          ??????????????????ServletConfig,是一個較重要的對象。

          ??????????????????????????????????????????功能:1,獲得初始化參數(shù)
          ???????????????????????????????????????????????????2,獲得Servlet上下文對象。public ServletContextgetServletContext()

          GeneralServlet抽象類,等待你去重寫service方法。

          ??????????????????功能主要就是,為程序員編寫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)

          ?????????????????????????????????????????????????????????因為GeneralServlet是個懶家伙,都委托給相應(yīng)ServletConfig/ServletContext完成功能


          HttpServlet沒什么,自己看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ù)的值有時會是一組,那么就要用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}&nbsp;</TD>
          ??? <TD height=30>${item.value.product.price}&nbsp;</TD>
          ??? <TD height=30><INPUT maxLength=10 size=10 value="${item.value.number}" name=itemnum></TD>
          ??? <TD height=30>${item.value.cost}&nbsp;</TD>
          ? </TR>
          ? </c:forEach>
          ????====================================================

          //獲得頁面,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.主要防止用戶在表單中輸入了中文。

          過濾器實例:

          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,就是負責輸出唄。

          ??????????????????????????????????????????????????????????????????????????????負責1:??public void setContentType(java.lang.String?type)?
          ????????????????????????????????????????????????????????????????????????????????????????????eg.?response.setContentType(text/html;charse=gbk)
          ??????????????????????????????????????????????????????????????????????????????負責2:? public java.io.PrintWriter getWriter() throws java.io.IOException
          ??????????????????????????????????????????????????????????????????????????????這里注意
          ????????????????????????????????????????????????????????????????????????????1必須先設(shè)置setContextType或者setCharacterEncoding,再獲得輸出。否則設(shè)置編碼無效!
          ????????????????????????????????????????????????????????????????????????????2不得在ResquestDispatcher.forward()調(diào)用前,進行向客戶端的輸出。有風險。
          ??????????????????????????????????????????????????????????????????????????????


          ServletContext整個應(yīng)用只有一個實例,可以為應(yīng)用放置一些只讀的共享數(shù)據(jù)。

          責任1:public java.lang.String getInitParameter(java.lang.String?name)
          責任2:public RequestDispatchergetRequestDispatcher(java.lang.String?path)絕對路徑
          責任3:public void log(java.lang.String?msg)


          Filter接口,實現(xiàn)對于某一個url匹配的過濾。是一個責任鏈模式的應(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)限過濾器?通過配置web.xml中的filter初始化參數(shù),實現(xiàn)動態(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包含這些頁面,那么就檢查是否登錄
          ???????????? {
          ????????????????
          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,如果有,直接返回,沒有創(chuàng)建??????? 等同于getSession()無參
          ?????????????????????????????????????????????????????????????????????????????????傳入false,沒有則返回null
          request.getRequestURI()???????????????????? /WebTest/servlet/MethodServlet
          request.getRequestURL()??????????????????? http://localhost:8080/WebTest/servlet/MethodServlet?

          URI是一個相對的位置,或者說就是一個標識,URL是資源定位,所以很精確。

          HttpServletResponse

          public void addCookie(Cookie?cookie)

          public java.lang.String encodeURL(java.lang.String?url)???????? URL回寫機制,說白了就是把jsessionid放在連接里,下回請求時就能穿回來了,不在需要Cookie了。注意,如果瀏覽器支持Cookie,無效果!!!

          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開發(fā)時,由于Session是在用戶訪問jsp時,自動創(chuàng)建的。如果能在用戶一訪問就往Session中放入一個容器對象呢,而不是在用戶發(fā)出某一個特定Action請求時,再判斷,再setAttribute();

          那么就用Listener吧,這時使用是一個完全充分的理由。[還有ServletContextListener]

          public void sessionDestroyed(HttpSessionEvent?se)???基本可以統(tǒng)計用戶在線時間。

          或者做考試系統(tǒng)時,會使用到。

          ====================================

          HttpSessionAttributeListener監(jiān)聽Session

          HttpSessionBindingListener監(jiān)聽被session的setAttribute方法加入的對象。

          實現(xiàn)接口的類型不同!!注意區(qū)分。

          ====================================

          HttpServletResponseWrapper

          是個適配器。

          在制作一個filter的時候,如果想在原有的輸出,某部分,添加一部分內(nèi)容,必須對HttpServletResponse進行適配。

          MyResponse myRes = new?MyResponse(response);
          chain.doFilter(request,myRes);
          String contents = myRes.toString();
          //解析字符串,比如尋找</body>

          myRes.getResponse().getWriter();//取回原來的response????????? ServletResponseWrapper有個有參的構(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 我就不廢話了,也就是一個內(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)建后,還沒讓客戶端知道呢!


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


          JSP

          就是一個Servlet

          <%
          ??????!
          %>??

          定義那個Servlet的成員

          ?<%!class ABC{}%>定一個類都沒有問題!

          表達式

          <%=request.getParameter("user")%>?????????????????????

          代碼段

          <%

          %>

          指令

          <% @page errorPage="relativeURL"%>
          <% @page isErrorPage="true"%>
          <% @page contextType="text/html;charset=gb2312" %>
          <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

          動作

          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這個標簽,還有一個屬性就是value,那么它的值是通過變化取得。

          jsp先回把html,翻譯成為xml的標準試圖,再使用一個引擎翻譯成為java代碼。

          <jsp:element name="h1">
          ???<jsp:attribute name="align">
          ??????center
          ???</jsp:attribute>
          ???<jsp:body>
          ??????This is the header!
          ???</jsp:body>
          </jsp:element>

          您把這段代碼放入jsp,可以通過的。

          <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默認為page

          這就是useBean指令做的事情。



          <jsp:useBean id="persons" type="java.util.Collection" scope="request" />

          注意type就是只說明它是什么類型的,不做實例化的步驟

          MVC中的視圖,就是使用集合bean的。如果不存在,會拋異常。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" />
          


          ====================================

          先來說說,JSTL和EL的東西

          Sun專門定制了一組標簽庫來完成頁面的程序流程控制,避免了代碼片斷的出現(xiàn)。而EL則避免了頁面出現(xiàn)表達式,而且對于attribute中的數(shù)據(jù)的非空驗證是自動完成。如果為空,只會出現(xiàn)沒有輸出內(nèi)容。

          EL還是比較簡單的。

          http://java.sun.com/products/jsp/syntax/2.0/syntaxref207.html#1010522

          上面是sun的教程。

          =====================================

          在說標簽和EL原理之前,必須把JSP的原理搞清楚。

          客戶端請求jsp,由一個翻譯引擎對jsp進行java代碼的翻譯,然后由容器進行編譯,加載到容器,invoke Servlet。

          一個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 >

          對應(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)置對象
          ????JspFactory?_jspxFactory?=?null;
          ????PageContext?pageContext?=?null;
          //使用page 指令中 Session=false,就不會出現(xiàn)session變量了,提高一些效率,注意只是不出現(xiàn)該引用。一訪問jsp/Session就創(chuàng)建了。只能通過SessionListener進行創(chuàng)建時的截獲,放置一些初始對象。
          ????HttpSession?session?=?null;
          ????ServletContext?application?=?null;
          ????ServletConfig?config?=?null;
          ????JspWriter?out?=?null;
          ????Object?page?=?this;
          ????JspWriter?_jspx_out?=?null;

          //關(guān)鍵的JSP上下文對象
          ????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ā)生編譯不過,就到tomcat的work目錄里看看java代碼,比較容易看到錯誤。jsp的提示對于嚴重的語法錯誤是不太友好的。


          對于隱含對象,就可以直接使用了。
          <%=request.getContextPath()%>

          <%=request.getInitParameter("user")%>

          對于JSP也可以配置初始化參數(shù)。

          web.xml對于JSP進行部署
          <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路徑不一樣,那么只有從這個pattern訪問的jsp才能獲得初始化參數(shù)。直接訪問jsp的沒有。
          =========================


          繼續(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
          ? extended byjavax.servlet.jsp.JspContext
          ????? extended byjavax.servlet.jsp.PageContext

          去查看一下PageContext這個父類型。

          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.

          看好這個方法是試圖從四個范圍內(nèi)取值,如果都取不到,就會返回null。

          public abstract void removeAttribute(java.lang.String?name)

          去除所有的屬性值。

          可以單獨設(shè)置,作用范圍

          public abstract void removeAttribute(java.lang.String?name,
          ???????????????????????????????????? int?scope)

          就是用子類PageContext設(shè)置的常量。

          ============================================================

          可以自己寫自定義標簽完成復雜的頁面表現(xiàn)功能。

          直接使用JSTL就行了。

          =======================

          JSTL配置EL,就可以使得JSP開發(fā)人員與JavaBean業(yè)務(wù)實現(xiàn)人員完全獨立工作。測試也可以獨立進行。

          因為使用EL語言,不再需要<jsp:useBean>指令來設(shè)置一個JavaBean的對象到某一個范圍內(nèi),并設(shè)置一個變量。

          使用EL,直接可以使用Attribute了。

          ${user.name}

          等價于

          判斷是否為空
          <%=user.getName()%>

          而且不需要判斷user是否為空。

          ---------

          EL有很多內(nèi)嵌對象,當然只限制于在EL表達式中使用。

          ${pageContext.request.contextPath}

          看到按照JAVABEAN命名的好處了吧,都可以按照標準命名去取值的。多方便。

          參數(shù)

          <c:if test=""${!empty param.username}">
          ??????do sth
          </c:if>

          訪問javabean

          ${bean1.a.c}

          相當于

          <%=bean1.getA().getC()%>

          注意getA()方法本身就是返回一個javabean對象,所以可以繼續(xù)javabean訪問。



          對于集合對象,Map對象。

          訪問可以通過另外的方式訪問。

          <%@?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}

          直接訪問屬性

          這只是一種簡單的情況,有時做應(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}&nbsp;</TD>
          ??? <TD height=30>${item.value.product.price}&nbsp;</TD>
          ??? <TD height=30><INPUT maxLength=10 size=10 value="${item.value.number}" name=itemnum></TD>
          ??? <TD height=30>${item.value.cost}&nbsp;</TD>
          ? </TR>
          ? </c:forEach>

          以上為一個購物籃的頁面的部分代碼:

          這設(shè)計時。Cart類 有一個HashMap集合保存著選購的Item。key為產(chǎn)品Id,而value是頁面需要展示的東西。

          是一個個Item對象。

          對于key為Id,或者頁面不關(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.

          也就是說Map里每一個元素是一個一個的Entry。

          再看看Entry方法。

          ?KgetKey()
          ??????????Returns the key corresponding to this entry.
          ?VgetValue()
          ??????????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

          如果做過自定義標簽的開發(fā),就很容易使用了。。



          ??<c:forEach?items="${cart.cartItem}"?var="item"?varStatus="i">
          ??
          <TR?align=middle>
          ????
          <TD?height=30>${i.count}&nbsp;</TD><%--?${i.index}??--%>
          ????
          <TD?height=30>${item.value.product.name}&nbsp;</TD>
          ????
          <TD?height=30>${item.value.product.price}&nbsp;</TD>
          ????
          <TD?height=30>${item.value.number}&nbsp;</TD>
          ????
          <TD?height=30>${item.value.cost}&nbsp;</TD>
          ??
          </TR>
          ??
          </c:forEach>


          =================

          struts真的太簡單了

          ActionServlet委托RequestProcessor完成功能。

          ActionForm有幾種??????? DynActionForm的使用和驗證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;
          ????}

          頁面

          <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);
          ????????}

          ????}


          =============

          驗證框架

          現(xiàn)在struts-config.xml注冊驗證的插件,

          <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

          這個接口就是插件接口,可以自己實現(xiàn)這個接口。

          按照人家ValidatorPlugIn的方式寫一個屬性,以便在struts-config.xml中描述插件時,提供具體值。

          pathnames

          ??? public String getPathnames()
          ??? {
          ??????? return pathnames;
          ??? }

          ??? public void setPathnames(String pathnames)
          ??? {
          ??????? this.pathnames = pathnames;
          ??? }


          StringTokenizer st = new StringTokenizer(pathnames, ",");


          -----------

          org.apache.struts.config.ModuleConfig

          該對象在init時傳入,可以利用來獲得struts-config.xml這個文件的信息。

          =====================

          DispatchAction就是對于不同form表單在同一Action中處理的解決方案,struts-config.xml在Action標記中加一個parameter屬性method,form的action則用function.do?method=add

          LookupDispatchAction就是對于同一個頁面不同的按鈕想都在一個Action中處理。需要重寫一個getMap方法。

          MappingDispatchAction就是每個方法一個Action標記對應(yīng)。



          最后就是使用令牌的方式來防止重復提交。

          org.apache.struts.action.Action

          這個父類的方法

          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)



          posted on 2006-03-12 18:14 北國狼人的BloG 閱讀(1538) 評論(1)  編輯  收藏 所屬分類: 達內(nèi)學習總結(jié)

          評論:
          # re: Servlet 2.4 和JSP 2.-的深入學習和Struts的輕松掌握 2007-02-07 12:00 | chris-in
          夠詳細的 !,學了不少的 東西! 3QQQQQ!  回復  更多評論
            
          主站蜘蛛池模板: 屏东县| 汨罗市| 嵊州市| 那曲县| 彰化市| 绵阳市| 定边县| 榕江县| 嘉黎县| 开平市| 玉山县| 新民市| 尼玛县| 临湘市| 景谷| 营山县| 通河县| 英吉沙县| 福清市| 托里县| 淮阳县| 镇坪县| 大庆市| 桂东县| 神池县| 饶河县| 巩义市| 浠水县| 遂川县| 洪江市| 铅山县| 金溪县| 卓资县| 灵丘县| 甘孜| 遂宁市| 常山县| 东乌珠穆沁旗| 丰都县| 德兴市| 顺义区|