jsp知識1

honghu79 12年前發布 | 1K 次閱讀 云計算 FUDforum Anonymous-OS
一、JSP model
JSP Model one :Jsp+javaBean:jsp頁面直接調用java的類,java類把業務的操作封裝起來   非主流的
JSP Model two: MVC在WEB項目中的具體應用

 JSP+JavaBean
  JSP model one   
   就是JSP頁面直接調用java類,java類把業務的操作封裝起來
 JSP+JavaBean已經慢慢不再用了。
  最主流的模式是MVC
   Struts
    要想用好Struts,要想理解JSP的原理
我們先寫一個山寨版本的Struts
 只有這樣我們才能理解什么是框架,我們要努力學習
二、MVC?
 我們主要是指導MVC在WEB項目中的具體應用。
  JSP  MODEL TWO
  在軟件工程中,基本上不會隨便升級模式的。因為升級模式,程序可能重構,程序員要重新學習
JSP model one:每一個JSP頁面之間可能存在錯綜復雜的關系
 |
 |     升級過程中,JSP重構
 |
 |
JSP MODEL TWO
MVC
M層:JavaBean   ----model很難理解,記住就行;主要是對業務數據的訪問
 1、包含dao
 2、包含domain中的類
C層:控制層(器)一般情況下用servlet來實現----沒頁面只有代碼;
 1、接受提交,處理請求(GET,POST)
 2、調用M
 3、選擇JSP去顯示結果
V層:model two里面的jsp   view層,只能干兩件事:1、顯示結果;2、通過表單提交數據

三、舉例子說明JSP model one,two:顯示用戶列表
 1、JSP MODEL ONE:jsp+javaBean
    user_list.jsp
    UserDao   訪問數據
    User類   負責封裝業務數據
    具體怎么功能:user_list.jsp與UserDao進行交互
    
    jsp: 1、接收請求 2、調用dao 3、顯示結果
    
 2、jsp model two
    user_list.jsp
    ****servlet(為什么是servlet不是一個普通類呢?因為要接收請求,類不能接收請求)--控制器
    UserDao
    User
    
    servlet:1、接收請求 2、調用 dao  3、把數據傳給jsp
    jsp:顯示結果
    
   瀏覽器-----〉servlet---->dao------>servlet---->jsp------>顯示結果
    重點在servlet---->jsp
     這里我們學習下轉化技術(就是為了MVC才學習轉發技術)
四、轉發技術
 重定向  瀏覽器------jsp(servlet)---->瀏覽器----〉另外一個servlet或者jsp ---〉瀏覽器     兩個請求
 轉發     瀏覽器-------Servlet(做完一段事情后)---->jsp(接著做事,響應)----〉瀏覽器        一個請求
 jsp頁面可以放到jsp下面
 tomcat 文件不允許瀏覽器訪問web-inf下面的文件。web-inf下面的文件都不能通過瀏覽器直接訪問.但是別的組件會通過轉發的方式來訪問
五:request和Session共享數據      
一個請求內部的不同組件之間共享數據用request
  request.setAttribute(arg0,arg1);
  request.getAtrribute(arg0,arg1);
多個請求之間共享數據用session,但是數據一直會存在session里面,用完最好直接清除。
    比如驗證碼
      1、一個生成驗證碼
      2、用戶填寫的驗證碼到服務器上與session中的驗證碼進行對比
六、
前端控制器:如果寫多個servlet的話,servlet之間的關系就像JSP時的關系一樣錯綜復雜。
   所以不管寫多少功能,要求servlet只有一個,但是通過
修改web.xml文件,把前端控制器叫ActionServlet;其url-pattern地址為*.action
 <servlet>
     <servlet-name>action</servlet-name>
      <servlet-class>org.whatisjava.controller.ActionServlet</servlet-class>
   </servlet>
  <servlet-mapping>
     <servlet-name>action</servlet-name>
     <url-pattern>*.action</url-pattern>
  </servlet-mapping> 
******************************************************************************************
假設訪問的地址為listUser.action時,就是看用戶列表;假設訪問的地址為:addUser時就是添加用戶
******************************************************************************************
package org.whatisjava.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.whatisjava.dao.UserDao;
public class ActionServlet extends HttpServlet {

 public void service(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  System.out.println("ActionServlet....");
  String uri=request.getRequestURI();
  //request.getRequestURI();//根據請求的url返回uri    ri(Returned Value)
  //For example: First line of HTTP request   Returned Value
  //POST   /some/path.html HTTP/1.1    /some/path.html 
  //GET   http://foo.bar/a.html HTTP/1.0  /a.html 
  //HEAD    /xyz?a=b HTTP/1.1     /xyz 
  //String path=uri.substring(uri.lastIndexOf("/"),uri.indexOf("."));
  //以上語句存在錯誤,使用下面語句通過
  String path=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
  //substring(int beginIndex,int endIndex);
  //從路徑中取出文件名;
  
  //System.out.println(path);
  if("/listUser".equals(path)){
   UserDao dao=new UserDao();
   List list=(List) dao.findAllUser();
   
   request.setAttribute("user_list", list);
   RequestDispatcher rd=request.getRequestDispatcher("WEB-INF/jsp/user_list.jsp");
   rd.forward(request, response);
   
   
  }else if("/addUser".equals(path)){
   //添加用戶
  
   
  }
  
  
 }
}
 //按照這種模式來做的話,這個serlvet將成了超級類
 
 
ActionServlet
ActionServlet(){
 if ()
 {
 }else if(){
 
 }
 
 }

我們怎么解決上面這個問題呢?
再做一個類叫Action;

package org.whatisjava.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class Action {
 public abstract String execute(HttpServletRequest request,HttpServletResponse response);
 //抽象類沒有實例,用的是其子類;意思是讓其子類長的一樣
 //抽象方法不會有實現
 
}
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
 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-app_2_4.xsd">
  <servlet>
    <servlet-name>ActionServlet</servlet-name>
    <servlet-class>org.whatisjava.controller.ActionServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ActionServlet</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 
*************************
ActionServlet
**********************
package org.whatisjava.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.whatisjava.dao.UserDao;
public class ActionServlet extends HttpServlet {

 public void service(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  System.out.println("ActionServlet....");
  String uri=request.getRequestURI();
  //request.getRequestURI();//根據請求的url返回uri    ri(Returned Value)
  //For example: First line of HTTP request   Returned Value
  //POST   /some/path.html HTTP/1.1    /some/path.html 
  //GET   http://foo.bar/a.html HTTP/1.0  /a.html 
  //HEAD    /xyz?a=b HTTP/1.1     /xyz 
  String path=uri.substring(uri.lastIndexOf("/"),uri.indexOf("."));
  //substring(int beginIndex,int endIndex);
  //從路徑中取出文件名;
  
  //System.out.println(path);
//  //*************************************
//  if("/listUser".equals(path)){
//   Action action=new ListUserAction();
//   
//   String forward=action.execute(request, response);
//   
//   RequestDispatcher rd=request.getRequestDispatcher(forward);
//   rd.forward(request, response);
//   
//   
//  }else if("/addUser".equals(path)){
//   //添加用戶
//   //按照這種模式來做的話,這個serlvet將成了超級類
//   
//   Action action=new AddUserAction();
//   
//   String forward=action.execute(request, response);
//   
//   RequestDispatcher rd=request.getRequestDispatcher(forward);
//   rd.forward(request, response);
//   
//  }
//  //*********
   Action action=null;
  if ("user_list".equals(path)){
   
   action=new ListUserAction();
  }else if("addUser".equals(path)){
   
   action=new AddUserAction();
  }
  //假設這個地方再增加一個功能比如deleteUser,還是需要修改程序?
  //怎么才能避免需要添加功能時不修改Action呢?
  //最好的是把其放到配置文件里面
  
  //根據配置文件決定new哪個類......
  //采用反射
  //String className;
  //Class.forName(className).newInstance();
  
  String forward=action.execute(request, response);
  
  RequestDispatcher rd=request.getRequestDispatcher(forward);
  rd.forward(request, response);
  
  
 }
}

**********************
ListUserAction
************************
package org.whatisjava.controller;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.whatisjava.dao.UserDao;
public class ListUserAction extends Action {
 //
 public String execute(HttpServletRequest request,
   HttpServletResponse response) {
  UserDao dao=new UserDao();
  List list=(List) dao.findAllUser();
  
  request.setAttribute("user_list",list);
  
  return "/WEB-INF/jsp/user_list.jsp";
 }
}

如何去解析一個特定格式的xml配置文件

1、首先要定義一個配置文件格式:
 <action-mappings> <!--根元素-->
  <action path="/listUser" type="ListUserServlet"/>
  <!--表示一個元素;一個路徑和類型的對應-->
  <action path="/addUser" type="AddUserServlet"/>
 </action-mappings>
 //一個action元素就表示了一個路徑和一個類型的對應
 //說明書:
  以后所有的程序員按照以上格式來寫配置文件
  程序首先要讀這個配置文件,根據path的請求信息.action前面的那個值來確定new哪個類
  然后通過反射的方式來new這個類。
  
2、通過組件commons-digester來解析配置文件
 兩種技術SAX    DOM這兩種模式都是比較底層的技術
 組件commons-digester專門用來解析配置文件(struts也是用這個組件來解析配置文件的)
 配置文件一般都是在啟動的時候讀配置文件,把其內容緩存到內存中
 digester組件的功能作用就是把xml的元素轉換成對象放到內存中。---這樣做,就是先要在內存中做一組類
 和配置文件是對應的,這樣就可以把xml的內容放到對象中了。
 根據上面的xml配置文件就相當于要做兩個類
 ActionMappings----代表根元素ActionMappings
 ActionMapping----代表action元素

創建兩個類
ActionMapping類
package org.whatisjava.controller;
public class ActionMapping {
 private String path;
 private String type;
 public ActionMapping(){
  
 }
 public String getPath() {
  return path;
 }
 public void setPath(String path) {
  this.path = path;
 }
 public String getType() {
  return type;
 }
 public void setType(String type) {
  this.type = type;
 }
 
 
}
ActionMappings類
package org.whatisjava.controller;
import java.util.HashMap;
import java.util.Map;
public class ActionMappings {
 //private Collection<ActionMapping> actions;
 //根據path找actionmapping,主要是用于查詢;
 
 //到底是用ArrayLIST,還是HashMap中呢?
 //HashMap是根據HashCode做索引的
 private Map<String,ActionMapping> actions=new HashMap<String,ActionMapping>();
 
 //Map是鍵值對
 
 
 //提供一個方法能讓外界訪問,能把數據放到map里面
 public void addActionMapping(ActionMapping mapping){
  actions.put(mapping.getPath(), mapping);
  //key為mapping的path作為鍵;
  //mapping自身為value
  
 }
 
 
 public ActionMapping findActionMapping(String path){
  
  return (ActionMapping)actions.get(path);
  
 }
}
 
假設已經有一個組件已經可以把xml配置文件的信息一下子幫我們灌輸到ActionMappings里面,在ActionServlet里面應該怎么做?

package org.whatisjava.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.whatisjava.action.AddUserAction;
import org.whatisjava.action.ListUserAction;
import org.whatisjava.dao.UserDao;
public class ActionServlet extends HttpServlet {
 private ActionMappings mappings=null;
 
 public void init(){
  //構造完了之后會調用以下init();
  //初始化mappings(讀取配置文件信息到mapings對象中)
  
 
 }
 
 
 
 public void service(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  System.out.println("ActionServlet....");
  String uri=request.getRequestURI();
  //request.getRequestURI();//根據請求的url返回uri    ri(Returned Value)
  //For example: First line of HTTP request   Returned Value
  //POST   /some/path.html HTTP/1.1    /some/path.html 
  //GET   http://foo.bar/a.html HTTP/1.0  /a.html 
  //HEAD    /xyz?a=b HTTP/1.1     /xyz 
  String path=uri.substring(uri.lastIndexOf("/"),uri.indexOf("."));
  //substring(int beginIndex,int endIndex);
  //從路徑中取出文件名;
  
  //System.out.println(path);
//  //*************************************
//  if("/listUser".equals(path)){
//   Action action=new ListUserAction();
//   
//   String forward=action.execute(request, response);
//   
//   RequestDispatcher rd=request.getRequestDispatcher(forward);
//   rd.forward(request, response);
//   
//   
//  }else if("/addUser".equals(path)){
//   //添加用戶
//   //按照這種模式來做的話,這個serlvet將成了超級類
//   
//   Action action=new AddUserAction();
//   
//   String forward=action.execute(request, response);
//   
//   RequestDispatcher rd=request.getRequestDispatcher(forward);
//   rd.forward(request, response);
//   
//  }
//  //*********
//   Action action=null;
//  if ("user_list".equals(path)){
//   
//   action=new ListUserAction();
//  }else if("addUser".equals(path)){
//   
//   action=new AddUserAction();
//  }
  //假設這個地方再增加一個功能比如deleteUser,還是需要修改程序?
  //怎么才能避免需要添加功能時不修改Action呢?
  //最好的是把其放到配置文件里面
  
  //根據配置文件決定new哪個類......
  //采用反射
  //String className;
  //Class.forName(className).newInstance();
  if (path==null) throw new ServletException("....."); 
  
  ActionMapping mapping=mappings.findActionMapping(path);
  
  if (mapping==null) throw new ServletException("...."); 
  
  
  try{  
  String className=mapping.getType();
  Class clazz=Class.forName(className);
  Action action=(Action) clazz.newInstance();
  
  String forward=action.execute(request, response);
  if (forward!=null){ 
  RequestDispatcher rd=request.getRequestDispatcher(forward);
  rd.forward(request, response);
  }
  }catch(Exception e){
   throw new ServletException("...");
   
  }
 }
}
 

導入commons-digest組件;將該包放到lib目錄下。用這個小組件還需要配置一個rule.xml文件
rule.xml文件
<?xml version='1.0' encoding='UTF-8'?>
<!--
 這個xml文件是由commons-digester定義用于告訴digester組件
  自定義的配置文件和配置對象之間的關系,commons-digester組件了解了這
 個關系后就可以將配置文件中的信息轉換為配置對象
-->
<digester-rules>
 <pattern value="action-mappings">
  <pattern value="action">
   <!--每碰到一個action元素,就創建指定類的對象-->
   <object-create-rule classname="org.whatisjava.controller.ActionMapping" />
   <!--
    對象創建后,調用指定的方法,
    將其加入它上一級元素所對應的對象
   -->
   <set-next-rule methodname="addActionMapping" />
   <!--
    將action元素的各個屬性按照相同的名稱
    賦值給剛剛創建的ActionMapping對象
   -->
   <set-properties-rule />
   
  </pattern>
 </pattern>
</digester-rules>
 
 
 
&&&&&&&&&&&&&&&&&*****************************
接下來要完成2個問題:
 a、框架的轉發和重定向問題
 b、action返回的是好多地址
框架變更:
 
修改下config.xml文件
<action-mappings>
 <action path="/registerForm" type="org.whatisjava.action.RegisterFormAction">
  <forward name="123" path="/1.jsp" redirect="true"/>
  <forward name="456" path="/2.jsp" redirect="false"/>
 //這兩個forward是定義在action里面的。一個forward包含name,path,redirect3個信息
   //redirect只能選擇true或者false
   //action返回的地址不是真正的地址,而是forward中指定name 123,或456,
   //如果返回123,path=1.jsp,
</action>
 
</action-mappings>
 
 
 本文由用戶 honghu79 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!