servlet+jsp05基礎知識

知識復習和擴充:
1、序列化和反序列化
 序列化可以理解為把java對象內存中的數據弄成一串二進制數據,然后把這些數據存放在可以持久化的數據存儲設備上。
 當需要還原這些數據的時候,再通過反序列化的過程,把對象數據重新還原到內存中。
 java.io.Serializable接口是可以進行序列化的類的標志性接口,僅用來告訴JVM該類的對象的可以進行的序列化。
 
 所有需要進行序列化的類,都必須實現Serializable接口,必要時還需要提供靜態的常量SerialVersionUID
 Java的IO提供過了一對類用作對象的序列化和反序列化,主要包括ObjectOutputStream和ObjectInputStream。
 序列化和反序列化的主要步驟:
  a、讓需要序列化的類實現java.io.Serializable
  b、提供靜態的long型 常量serialVerisonUID
  c、如果是序列化對象,則用一個輸出流創建一個ObjectOutputStream對象,然后調用writeObject()方法
  d、如果是反序列化對象,則使用一個輸入流創建一個 ObjectInputStream對象,然后調用readObject(),
   得到一個Object類對象,然后再強轉。
  e、最后關閉流
  ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("c:/web/obj.dat"));
  oos.writeObject(要序列化的類class);
  oos.close();
 
  ObjectInputStream ois=new ObjectInputStream(new FileInputStream("c:/web/obj.dat"));
  Object obj=ois.readObject();
  Student stu1=(Student)obj;
  
 
2、JSP的運行機制
 JSP(Java Server Page)是一種建立在Servlet規范提供的功能之上的動態網頁技術。
 JSP文件會在用戶第一次請求時,web容器(如tomcat)會將該文件編譯成servlet,再由該servlet出來用戶請求。
 web容器處理請求的過程:
  a、會檢驗JSP語法是否正確
  b、將該JSP文件轉換成Servlet源文件
  c、編譯該源碼文件成為class文件
  d、創建一個servlet類的對象實例,以servlet的方式為請求提供服務。
3、List、Set、Map
 List:有序存放,可以重復,可以存放不同類型的對象;
 Set:無序存放,不能重復,可以存放不同類型的對象;
 SortedSet:排好序列的Set;
 Map:鍵值對
 SortedMap:排好序列的Map
 備注:所有的集合實現類,存放的是對象,需要存放基本數據類型的數據,則需要使用其包裝類。
 能夠迭代查詢,Iterator,forEach
5、理解HttpSession
 原理:服務器端的對象,可以用于存儲對象
     通過SessionID標識
     SessionID通過cookie來保持
  /*
   * 如果當前的請求信息中有帶有存儲
   * Session ID的Cookie,且該Session ID
   * 對應的Session對象存在,則返回該對象
   *
   * 否則,該方法將創建新的Session對象
   * 并且將新產生的Session ID 作為Cookie
   * 通過響應存到瀏覽器端
   */
  HttpSession session = request.getSession();
  
  System.out.println(session.getId());
  
  // void setAttribute(String, Object)
  session.setAttribute("date", new Date());
  
  
  session.setMaxInactiveInterval(60*30);
  //設置最大的不活動時間
  
  // 讓Session馬上失效,一般用在login的登出
  //session.invalidate();
  
  // Object getAttribute(String)
  Object obj = session.getAttribute("date");
  System.out.println(obj);
6、Session注意的問題
 1、session中的數據不能過大
 2、會話范圍,關閉瀏覽器session“失效”?
    能否不快速失效,因為默認的cookie的最大生存時間為負數,修改下即可。
 3、最大的不活動時間maxInactiveInterval
    控制session對象在服務器端的時效
 4、Session的序列化
    服務器關閉的時候會將其序列化成文件,啟動起來的時候會反序列化
API
 setAttribute
 getAttribute
 setMaxInactiveInterval
 invalidate
 getSessionoId
7、分頁
  分頁查詢:只是把數據取一部分出來顯示
  分頁顯示:就是把數據全部取出來,只顯示一部分
 
 分頁顯示:結果都拿出來,然后再分頁顯示
   select * from emp;
   ...
   int n=1;
   while(rs.next()){
   if (++n>10)
   {
   
   }
   }
 惰性加載
  ResultSet 通過select * from emp查詢記錄時,可能會從100w條記錄內查詢
  實際上并沒有將100w條記錄全部加載到內存中。
  可能通過設置只顯示100條記錄。
  當游標來訪問1-100條記錄時,直接訪問即可,當超過100條記錄時
  會繼續將其他記錄加載到內存中,記錄越來越多,會出現內存不夠
 所以,對大數據量來說,分頁顯示是不行的
***用可滾動的結果集還是游標的next來做分頁顯示效果都是一樣的。只是可滾動的結果集變成要簡單些而已***
 
了解IO中的skip(100)

 分頁查詢
  
  a、oracle用rownum偽列
  select id,name,sal from(select id,name,sal rownum num from emp where rownum<?) where num>=?;
  b、mysql用limit
  select id,name,sal from emp limit (?,?);
  第一個問號表示從哪里開始取
  第二個問號表示一共取幾個
8、在web工程中的classes類路徑下載入資源文件
 讀取數據庫的配置文件
  SomeClass.class.getClassLoader().getResourceAsStream("org/whatisjava/dao/db.properties");

5、jsp+javaBean的編程模式
 一堆jsp、一堆java類(封裝對數據庫的增刪改查)
  jsp分三類:1、顯示jsp
       2、表單jsp:收集用戶信息,提交給另外一個jsp
       3、接收jsp:接收用戶的輸入。進行一個操作,添加一個員工
需求:
 員工列表
  姓名   id    salary
 

  上一頁  2   下一頁
  一、table
   emp
  二、javaBean
   首先要想好類名;一般情況下,一個表,對應一個Dao
   Emp
   EmpDao  封裝一些方法,對員工數據的增加刪除改動查詢
  三、jsp頁面
   emp_list
  瀏覽器          jsp              DAO
   | ——〉  |  方法  |    獲得第一頁的數據
   |     |————〉  |
   | <——  |     |
   | ——〉  |     |   再次發請求,必須顯示哪一頁n的請求
    |     |————〉  |方法n
    |  <—— |     |
   |     |     |
   |     |     |隱含存在一個返回一個總的頁數
   |     |     |
 
 
9、文件的上傳
 <form action="upload" method="post" enctype="multipart/form-data">
  ============================================================
      <table cellpadding="0" cellspacing="0" border="0"
       class="form_table">
       <tr>
        <td valign="middle" align="right">
         上傳你的照片
        </td>
        <td valign="middle" align="left">
         <input type="file" class="inputgri" name="file1" />
         ==================================================
         //會在頁面中顯示一個文本框和一個瀏覽按鈕
        </td>
       </tr>
      </table>
      <p>
       <input type="submit" class="button" value="提交 &raquo;" />
      </p>
 </form>

上傳圖片
抓包分析:
協議頭
  POST
  Content-Type:multipart/form-data;  boundary=------------7d392939239239234
  ....
 
    用邊界隔開的數據塊
 =------------7d392939239239234
 Content-disposition:form-data;name="file1";filename=""
 Content-type:image/jpg

*******如果服務器把這個東西讀取出來就相當于把數據上傳了。服務器端需要具備能識別這些數據塊的組件。
服務器端需要具備能識別這些數據塊的組件
我們希望用現成的組件來讀取協議里面的東西Apache Commons

企業里面希望我們寫出山寨版本的spring,struct,hibernate;怎么寫呢?
 實際上大多數框架都是引進了一些小的框架比如hibernate中采用了cglib延緩加載
 也就是把小的框架了解清楚了,才能逐步的寫出山寨版的
 
 apache Commons
 Commons
Commons
文件上傳:
 
 首先把commons-fileupload-1.2.1.jar復制到項目的lib目錄下
 可以做個servlet來實現表單的上傳
 
package org.whatisjava.servlet;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet extends HttpServlet {
 public void service(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  try {
   // 用于設定諸如緩存之類的參數,和性能相關
   // 此處用默認設定
   DiskFileItemFactory dfif = new DiskFileItemFactory();
   //文件項工廠
   // 解析表單中的數據
   ServletFileUpload upload = new ServletFileUpload(dfif);
   //ServletFileUpload是重點
   
   upload.setSizeMax(10 * 1024 * 1024);
   // 允許上傳的最大值
   //如果超過這個設置,將不再解析,防止惡意攻擊
   List list = upload.parseRequest(request); // 開始解析request對象中的表單數據
   // list中是FileItem對象
   // 一個FileItem用于封裝一個上傳的文件數據
   
   if (list.size() >= 1) {
    FileItem item = (FileItem) list.get(0);
    
    String name = item.getName();
    // 獲得上文件的路徑名
    
    name = name.substring(name.lastIndexOf("\\") + 1);
    // 把上傳的文件數據寫入本地文(服務器端)件
    String path = "pic";
    // Sun的標準,服務器實現的API
    ServletContext ctx = this.getServletContext();
    path = ctx.getRealPath(path);
    
    
    System.out.println(path);
    item.write(new File(path, "default.jpg"));
    //查看api,new File
    response.sendRedirect("upload_form.jsp");
   }
  } catch (Exception e) {
   throw new ServletException("file upload error!", e);
  }
 }
}
 
String path = "pic";    
//sun公司的標準;tomcat服務器實現的api
//ServletContext   servlet的上下文
//
ServletContext  ctx=this.getServletContext()
 
//getServletContext;   將相對路徑轉換成絕對路徑
path = ctx.getRealPath(path);      

//上傳圖片后,個別時候由于存在緩存,所以可能個別時候不能更改----怎么處理?

10、練習電子相冊系統
a、每個用戶可以建立自己的個人用戶信息,上傳自己的圖片;
b、游客只能看用戶列表,
c、如果需要看姓名,必須登陸,如果沒有賬戶則須注冊
d、用戶列表
 姓名    年齡   所在地
 姓名是超鏈接能出來詳細的信息,也能看到自己上傳的圖片
e、加上驗證碼
f、登錄和注冊模塊
table
 t_user
  u_id   //唯一的主鍵
  u_username  //最好用email注冊
  u_password
  u_name
  u_age
  u_sex
  .....
  u_pic  //上傳圖片的路徑
   該路徑可以由pic_uid來區分
  對應每一個用戶有一個圖片庫,最好是另外一臺服務器
  
     
 ***假設放置到實際案例中前臺采用F5來實現負載均衡,批量的并發用戶來自全省各地,怎么分攤其負載呢?
 *** 上傳路徑不僅要考慮存儲的目錄還要考慮上傳到哪個服務器上了。
 *** 服務器之間數據同步問題?同步時影響帶寬和性能問題?
 *** 還是通過磁盤陣列提供的mirror功能來實現數據同步?
首先把登錄和注冊寫了
 1、登錄成功后,定位到一個頁面,并把登錄成功的信息放到session里面
 2、注冊是在數據庫中增加一個用戶
 
通過Eclipse如何能夠連接數據庫
windows菜單下references—MyEclipse——Database Explorer——database drivers--- 
 DB Browser
  new
  連接mysql或者oracle數據庫
  

Eclipse如何能夠支持hibernate
 選中工程----myEclipse---add hibernate capacity
 從數據庫中選中表,Hibernate reverse engineering
  反向工程
  src
  是否生成映射文件、pojo
  Hibernate.cfg.xml
  HibernateSessionFactory

需要封裝什么樣的方法呢?
 登錄和注冊
  注冊主要是插入一個用戶 
  登錄,我們要把用戶名和密碼給他,并且登錄成功后,我們要把其信息放到session里面
  

<%@page pageEncoding="utf-8"%>
 在eclipse中一讀取到該信息,則會自動地將該頁面以utf-8方式
 
<%@page pageEncoding="utf-8"%>
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title></title>
  <link rel="stylesheet" type="text/css" href="css/style.css" />
 </head>
 <body>
  <div id="wrap">
   <div id="top_content">
    <%@include file="header.jsp"%>
    <div id="content">
     <p id="whereami">
     </p>
     <h1>
      注冊
     </h1>
     <form action="register.jsp" method="post">
      <table cellpadding="0" cellspacing="0" border="0"
       class="form_table">
       <tr>
        <td valign="middle" align="right">
         用戶名:
        </td>
        <td valign="middle" align="left">
         <input type="text" class="inputgri" name="username" />
        </td>
       </tr>
       <tr>
        <td valign="middle" align="right">
         真實姓名:
        </td>
        <td valign="middle" align="left">
         <input type="text" class="inputgri" name="name" />
        </td>
       </tr>
       <tr>
        <td valign="middle" align="right">
         密碼:
        </td>
        <td valign="middle" align="left">
         <input type="password" class="inputgri" name="pwd" />
        </td>
       </tr>
       <tr>
        <td valign="middle" align="right">
         性別:
        </td>
        <td valign="middle" align="left">
         男
         <input type="radio" class="inputgri" name="sex" value="m" checked="checked"/>
         女
         <input type="radio" class="inputgri" name="sex" value="f"/>
        </td>
       </tr>
       
       <tr>
        <td valign="middle" align="right">
         驗證碼:
         <img id="num" src="image" />
         <a href="javascript:;" onclick="document.getElementById('num').src = 'image?'+(new Date()).getTime()">換一張</a>
         ==================================================================
                   // 欺騙服務器
       //重點部分:?????
       //img id="num"
       //
        </td>
        <td valign="middle" align="left">
         <input type="text" class="inputgri" name="number" />
        </td>
       </tr>
      </table>
      <p>
       <input type="submit" class="button" value="Submit &raquo;" />
      </p>
     </form>
    </div>
   </div>
   <%@include file="foot.jsp"%>
  </div>
 </body>
</html>
<a href="#">換一張</a>刷新本頁
<a href="http://.....">換一張</a>連接到某地址
<a href="JavaScript:alter("abc")">換一張</a>
<a href="JavaScript:;" onclick="document.getElementById('num').src='image?'+(new Date()).getTime()">換一張</a>
這句話是在瀏覽器中運行,不是在服務器端運行
其中document.getElementById是獲得 image這個元素.src是改這個屬性;new Date()是javascript里面的date而非java中的date
為什么呢?如果瀏覽器在某個時刻發現頁面上某個地方變了會重新向新地址發請求
<img src="image">
<img src="image?17272772727">
服務器收到信息后,會以為?后面是參數,但是又是一個錯誤的參數。。訪問的還是原來的地址
相當于欺騙服務器
 

如何將表單的數據一下子灌到user類對應的表中
<%@page import="org.whatisjava.dao.*" %>
<%@page import="org.whatisjava.domain.*" %>
<%@page import="java.util.*" %>
<%@page import="org.apache.commons.beanutils.*" %>
<%
//請求提交過來首先要判斷下驗證碼是否準確
//提交的表單里面的數據是什么?
String number1=request.getParameter("number");
String number2=(String)session.getAttribute("number");
if (number2!=null && number2.equals(number1)){
 UserDao dao=new UserDao();
 User user=new User();
 //user.setUsername(request.getParameter("username"));
 //.....
 //這樣的語句會寫一大串,由于request里面的都是文本內容,可能還存在強轉之類語句
 //一般情況下,一項項來寫的話,編程特別多,有沒有一種方式或方法一下子把數據
  //全部灌到user里面呢
  //可以采用commons特殊組件  commons-beansUtils組件
 //BeanUtils.;
 Map map=request.getParameterMap();
 BeanUtils.populate(user, map);//把map數組填充到user里面,在填充的時候已經把類型轉換好了。
 //用戶提交了一個user{},map就做成數組了。
 //user {aaa}
 //password {bbb}
 //lanaguage(checkbox){a,b,c,abc} //對應多個值
 
 //能夠實現這種填充的是關鍵是:哪一個表單名字應該知道user的哪一個屬性。
 //最好的就是把表單中的名字和user的set和get方法的名字相同即可
 
 dao.addUser(user);
 
 response.sendRedirect("login_form.jsp");
 
  
 //System.out.println(map);//在控制臺上打印出map
 
}else {
 response.sendRedirect("register_form.jsp");
 
}
 
%>
 
 
 

hibernate 映射文件
 類的getXxxxx,setXxxx方法來進行的映射

 
 本文由用戶 honghu79 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!