Web應用
一個好的Web應用:
??功能完善
? 易于實現和維護
? 易于擴展等
的體系結構
一個Web應用通常分為兩個部分:
(主要做網頁界面設計)
(主要完成本Web應用的各種功能)
Web開發的兩種常用模式
Web開發的兩種常用模式
Model1 純JSP或JSP+javabean
適用于小型的Web應用

優點:簡單,所見即所得,容易實現
缺點:訪問數據庫的代碼需要寫在JSP頁面中,如果數據庫發生變化,JSP頁面需要重寫
2.使用JSP+JavaBean
優點:數據訪問代碼和JSP頁面分離,數據訪問代碼重用性好
缺點:系統復雜時,JSP頁面中仍會包含大量腳本代碼,代碼開發和維護困難
Model2 MVC模式
? ?模型2其實就是一種MVC體系結構,也稱為MVC模型2。該模型是一種將應用分解成三個獨立部分的通用模型。
MVC好處



MVC模式來實現用戶注冊
1.模型(JavaBean) -
?? useBe.Register.class
package useBe;
public class Register
{?? String logname="",password="",email="";
??? String backNews;
??? public void setLogname(String name)
??? {? logname=name;
??? }
?? public String getLogname()
??? { return logname;
??? }
?? public void setPassword(String pw)
??? {? password=pw;
??? }
?
?public String getPassword()
??? { return password;
??? }
?? public void setEmail(String em)
??? {? email=em;
??? }
?? public String getEmail()
??? {? return email;
??? }
?? public String getBackNews()
??? { return backNews;
??? }
?? public void setBackNews(String s)
??? { backNews=s;
??? }
}
2.控制器(servlet) -
?? useSe.HandleRegister.class
package useSe;
import? useBe.Register;
import java.sql.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HandleRegister extends HttpServlet
{?? public void init(ServletConfig config) throws ServletException
??? { super.init(config);
????? try {? Class.forName("com.mysql.jdbc.Driver");
????????? }
?????? catch(Exception e){}
??? }
?? public String handleString(String s)
?? {?? try{ byte bb[]=s.getBytes("iso-8859-1");
??????????? s=new String(bb);
????????? }
?????? catch(Exception ee){}
?????? return s;?
?? }
?void? doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException
??? {?? Connection con;
??????? Statement sql;
Register reg=new Register();?? //創建Javabean對象
??????? request.setAttribute("register",reg);//將dataBean存儲到request對象中
??????? String logname=request.getParameter("logname").trim(),
??????? password=request.getParameter("password").trim(),
??????? email=request.getParameter("email").trim();
??????? String uri="jdbc:mysql://127.0.0.1:3306/test1";
??????? if(logname==null)
?????????? logname="";
??????? if(password==null)
?????????? password="";
??????? boolean isLD=true;????
?????? for(int i=0;i<logname.length();i++)
??????? {? char c=logname.charAt(i);
?????????? if(!((c<='z'&&c>='a')||(c<='Z'&&c>='A')||(c<='9'&&c>='0')))
???????????? isLD=false;
??????? }
??????? boolean boo=logname.length()>0&&password.length()>0&&isLD;
??????? String backNews="";
??????? try{ con=DriverManager.getConnection(uri,"root","123456");
???????????? String insertCondition="INSERT INTO member VALUES ('"+logname+"','"+password+"','"+email+"')";
???????????? sql=con.createStatement();
???????????? if(boo)
???????????? { int m=sql.executeUpdate(insertCondition);
?????????????? if(m!=0)
???????????????? {? backNews="注冊成功";
??????????????????? reg.setBackNews(backNews);
??????????????????? reg.setLogname(logname);
??????????????????? reg.setPassword(handleString(password));
??????????????????? reg.setEmail(handleString(email));
????????????????? }
????????????? }
???????????? else
????????????? {? backNews="信息填寫不完整或名字中有非法字符";
???????????????? reg.setBackNews(backNews);?
????????????? }
???????????? con.close();
?????????? }
??????? catch(SQLException exp)
????????? {? backNews="該會員名已被使用,請您更換名字"+exp;
???????????? reg.setBackNews(backNews);
????????? }
??????? RequestDispatcher dispatcher=request.getRequestDispatcher("show.jsp");//請求show.jsp顯示信息
??????? dispatcher.forward(request, response);
??? }
?? public? void? doGet(HttpServletRequest request,HttpServletResponse response)
??????????????????????? throws ServletException,IOException
??? {?? doPost(request,response);
??? }
}
MVC模式來實現用戶注冊
3.視圖(jsp)
register.jsp
<%@ page contentType="text/html;charset=GB2312" %>
<head>
<table>
?<td><A href="register.jsp"><font size=5>用戶注冊</font></A></td>
</table>
</head>
<HTML><BODY bgcolor=cyan><Font size=5><CENTER>
<FORM action="helpRegister" name=form>
<table>
??? 輸入您的信息,用戶名稱必須由字母和數字組成,帶*號項必須填寫。
?? <tr><td>用戶名稱:</td><td><Input type=text name="logname" >*</td></tr>
?? <tr><td>設置密碼:</td><td><Input type=password name="password">*</td></tr>
?? <tr><td>電子郵件:</td><td><Input type=text name="email"></td></tr>
?? <tr><td><Input type=submit name="g" value="提交"></td></tr>
</table>
</Form></CENTER>
</Body></HTML>
show.jsp
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="useBe.Register"%>
<jsp:useBean id="register" type="useBe.Register" scope="request"/>
<head>
<table>
?<td><A href="register.jsp"><font size=5>用戶注冊</font></A></td>
</table>
</head>
<HTML><BODY bgcolor=yellow>
<CENTER>
? <Font size=5 color=blue >
??? <BR><jsp:getProperty name="register"? property="backNews"/>
? </Font>
<table>
?<tr><td>注冊的名稱:</td>
???? <td><jsp:getProperty name="register" property="logname"/></td>
?</tr>
?<tr><td>注冊的電子郵件:</td>
???? <td><jsp:getProperty name="register" property="email"/></td>
?</tr>
</table>
</CENTER></BODY></HTML>
??? MVC模式的核心思想是有效地組合“視圖”、“模型”和“控制器”。
????? 本章將介紹MVC模式,掌握該模式對于設計合理的Web應用以及學習使用某些流行的Web框架,如Hibernate,Spring,Struts等,都有著十分重要的意義。
??? MVC是一種通過三個不同部分構造一個軟件或組件的理想辦法:
模型(Model)——用于存儲數據的對象。
視圖(View)——為模型提供數據顯示的對象。
控制器(Controller)——負責具體的業務邏輯操作,即控制器根據視圖提出的要求對數據做出處理,并將有關結果存儲到模型中,同時負責讓模型和視圖進行必要的交互,當模型中的數據變化時,讓視圖更新顯示。
??? 在JSP技術中,“視圖”、“模型”和“控制器”的具體實現如下:
模型(Model):
?? 一個或多個JavaBean對象,用于存儲數據,JavaBean主要提供簡單的setXXX()方法和getXXX()方法,在這些方法中不涉及對數據的具體處理細節。
視圖(View):
??? 一個或多個JSP頁面,為模型提供數據顯示,JSP頁面主要使用 HTML標記和JavaBean標記來顯示數據。
控制器(Controller):
??? 一個或多個Servlet對象,根據視圖提交的要求進行數據處理操作,并將有關的結果存儲到JavaBean中,然后Servlet使用重定向方式請求視圖中的某個JSP頁面更新顯示。
?在JSP+Javabean模式中,由JSP頁面通過使用useBean標記:
<jsp:useBean id="名字" class="創建bean的類" scope="生命周期"/>創建Javabean。
??? JSP中的MVC模式中,也可以由控制器servet創建Javabean,并將有關數據存儲到所創建的Javabean中,然后servlet請求某個JSP頁面使用Javabean的getProperty動作標記:
<jsp:getProperty name= "名字" property="bean的屬性"/>
顯示Javabean的中的數據。
??? 在JSP中的MVC模式中,非常重要的手段是由servlet負責用構造方法創建Javabean,因此允許創建Javabean的類可以有帶參數的構造方法。
???? 在JSP中的MVC模式中,servet創建的Javabean也涉及到生命周期(有效期限),生命周期分為request、session和application。以下假設創建Javabean的類的名字是BeanClass,該類的包名為user.yourbean 。
?request周期的Javabean
?? 1.Javabean的創建
?? servlet負責創建bean。那么創建生命周期為request的bean的步驟如下:
(1)用BeanClass類的某個構造方法創建bean對象,例如:
???????? BeanClass bean=new BeanClass();
(2)將所創建的bean對象存放到HttpSerletRequest對象request中,并指定查找該bean的關鍵字,該步驟決定了bean的生命周期為request。例如:
??????? request.setAttribute("keyWord",bean);
執行上述操作,就會把bean存放到Tomcat引擎管理的內置對象pageContext中,該bean被指定的id是"keyWord",生命周期是??
?????? PageContext.REQUEST_SCOPE(request)。??
2?? 視圖更新
??? servlet請求一個JSP頁面,比如show.jsp的代碼如下:
RequestDispatcher dispatcher= request.getRequestDispatcher("show.jsp");
dispatcher.forward(request,response);
??? servlet所請求的JSP頁面可以使用如下標記獲得servlet所創建的bean的引用(type屬性使得該JSP頁面不負責創建bean):
<jsp:useBean id="keyWord" type="user.yourbean.BeanClass" scope="request"/>
該標記中的id是servlet所創建的bean索引關鍵字。然后JSP頁面使用<jsp:getProperty name="keyWord" property="bean的變量"/>標記顯示bean中的數據。如果上述代碼執行成功,用戶就看到了show.jsp頁面的執行效果。
??? 特別注意: 如果servlet所請求的JSP頁面,使用如下標記獲得servlet所創建的bean的引用(注意沒有用type屬性而是用class屬性):
? <jsp:useBean id="keyWord" class="user.yourbean.BeanClass" scope="request"/>
該標記中的id是servlet所創建的bean索引關鍵字。那么即使servlet所請求的JSP頁面事先已經有了id是"keyWord",scope是"request"的bean,那么這個bean也會被servlet所創建的bean替換。
???? 原因是servlet所請求的JSP頁面會被刷新,就會根據當前頁面使用的<jsp:useBean id="keyWord" class="user.yourbean.BeanClass" scope="request"/> 標記到Tomcat引擎管理的內置對象PageContext中尋找id是"keyWord",生命周期是request,而該bean已經被servlet更新了。
? ?session周期的Javabean
??? 1.Javabean的創建
?? servet創建生命周期為session的bean的步驟如下:
(1)用BeanClass類的某個構造方法創建bean對象,例如:
??? BeanClass bean=new BeanClass();
(2)將所創建的bean對象存放到HttpSerletSession對象:session中,并指定查找該bean的關鍵字,該步驟決定了bean的生命周期為session。例如:
???? HttpSession session=request.getSession(true);
???? session.setAttribute("keyWord",bean);
?? 內置對象執行上述操作,就會把bean存放到Tomcat引擎管理的內置對象pageContext中,該bean被指定的id是"keyWord",生命周期是PageContext.SESSION_SCOPE(session)。??
?? 2?? 視圖更新
??? servelt創建bean, bean的生命周期為session,只要用戶的session沒有消失,該bean就一直存在,一個用戶在訪問Web服務目錄的各個JSP中都可以使用<jsp:useBean id="keyWord" type="usern.yourbean.BeanClass" scope="session"/> 標記獲得servlet所創建的bean的引用,然后使用<jsp:getProperty name="keyWord" property="bean的變量"/>標記顯示該bean中的數據,該標記中的id是servlet所創建的bean索引關鍵字。
??? 對于生命周期為session的bean,如果servlet希望某個JSP顯示其中的數據,可以使用RequestDispatcher對象向該JSP頁面發出請求,也可以使用HttpServletResponse類中的重定向方法(sendRedirect)。
??? show.jsp頁面使用如下標記獲得servlet所創建的bean的引用(注意沒有用type屬性而是用class屬性):<jsp:useBean id="keyWord" class="user.yourbean.BeanClass" scope="session"/>該標記中的id是servlet所創建的bean索引關鍵字。那么即使servlet所請求的JSP頁面或其他頁面事先已經有了id是"keyWord",scope是" session "的bean,那么這個bean也會被servlet所創建的bean替換。
???? 原因是,servlet所請求的JSP頁面或其他頁面被刷新時,就會根據當前頁面使用的<jsp:useBean id="keyWord" class="user.yourbean.BeanClass" scope=" session "/>標記到Tomcat引擎管理的內置對象PageContext中尋找id是"keyWord",生命周期是session,而該bean已經被servlet更新了。
?application周期的Javabean
? ?1.Javabean的創建
??? servet創建生命周期為application的bean的步驟如下:
(1)用BeanClass類的某個構造方法創建bean對象,例如:
???????? BeanClass bean=new BeanClass();
(2)servlet使用getServletContext()方法返回服務器的ServletContext內置對象的引用,將所創建的bean對象存放到服務器這個ServletContext內置對象中,并指定查找該bean的關鍵字,該步驟決定了bean的生命周期為application,例如:
????? getServletContext().setAttribute("keyWord",bean);
上述操作,就會把bean存放到Tomcat引擎管理的內置對象pageContext中,該bean被指定的id是"keyWord",有效期限是(生命周期)PageContext.APPLICATION_SCOPE(application)。?
2?? 視圖更新
??? 當servlet創建創建生命周期為application的bean后,只要Web應用程序不結束,該bean就一直存在。一個用戶在訪問Web服務目錄的各個JSP中都可以使用<jsp:useBean id="keyWord" type="user.yourbean.BeanClass" scope="application"/>? 標記獲得servlet所創建的bean的引用,然后使用
<jsp:getProperty name="keyWord" property="bean的變量"/>標記顯示該Javabean中的數據,該標記中的id是servlet所創建的bean索引關鍵字。
??? 對于生命周期為application的bean,如果servlet希望某個JSP顯示其中的數據,可以使用RequestDispatcher對象向該JSP頁面發出請求,也可以使用HttpServletResponse類中的重定向方法(sendRedirect)。
?? ?注意:所有用戶在同一個Web服務目錄中的application生命周期的bean是相同的,即占有相同的內存空間。另外,如果servlet所請求的JSP頁面,比如show.jsp頁面,使用如下標記獲得servlet所創建的bean的引用(注意沒有用type屬性而是用class屬性):<jsp:useBean id="keyWord" class="user.yourbean.BeanClass" scope="application"/>該標記中的id是servlet所創建的bean索引關鍵字。那么即使servlet所請求的JSP頁面或其他事先已經有了id是"keyWord",scope是"application"的bean,那么這個bean也會被servlet所創建的bean替換。
?? 原因是,servlet所請求的JSP頁面或其他頁面被刷新時,就會根據當前頁面使用的:<jsp:useBean id="keyWord" class="user.yourbean.BeanClass" scope="application"/>標記到Tomcat引擎管理的內置對象PageContext中尋找id是"keyWord",生命周期是application,而該bean已經被servlet更新了。
?Javabean和Servlet與配置文件
?? Javabean類的包名均為mybean.data;Servlet類的包名均為myservlet.control。
1.保存Javabean類和Servlet類的源文件
??? D:\ mybean\data? 和? D:\myservlet\control
2.編譯Javabean類
??? D:\javac mybean\data\Javabean的源文件
3.編譯Servlet類
??? D:\ javac myservlet\control\servlet的源文件
4.將類的字節碼文件保存到服務器
???? ch9\WEB-INF\classes\mybean\data
???? 和ch9\WEB-INF\classes\myservlet\control
5.web.xml文件
?? 編寫web.xml文件,并保存到Web服務目錄的WEB-INF子目錄中,即ch9\WEB-INF中 。??
MVC模式與注冊登錄??? 大部分Web應用都會涉及到注冊與登錄模塊。本節使用MVC模式講述怎樣設計注冊、登錄模塊。為ch9\WEB-INF中的web.xml文件添加如下子標記
?? ?Javabean與Servlet管理
??? 本節的Javabean類的包名均為mybean.data;Servlet類的包名均為myservlet.control。
1.保存Javabean類和Servlet類的源文件
?? D:\ mybean\data 和 D:\myservlet\control
2.編譯Javabean類
???? D:> javac mybean\data\Javabean的源文件
3.編譯Servlet類
????? D:> javac myservlet\control\servlet的源文件
4.將類的字節碼文件保存到服務器
???? ch9\WEB-INF\classes\mybean\data?? 和
???? ch9\WEB-INF\classes\myservlet\control??
配置文件管理
??? 本節的Servlet類的包名均為myservlet.control,需要配置Web服務目錄的web.xml文件,即將下面的web.xml文件保存到Tomcat安裝目錄的Web服務目錄ch9中。根據本書使用的Tomcat安裝目錄及Web服務目錄,需要將web.xml文件保存到
D:\apache-tomcat-8.0.3\webapps\ch9\WEB-INF
目錄中。????
web.xml
<servlet>
??? <servlet-name>register</servlet-name>
??? <servlet-class>myservlet.control.HandleRegister</servlet-class>
</servlet>
<servlet-mapping>
?? <servlet-name>register</servlet-name>
?? <url-pattern>/helpRegister</url-pattern>
</servlet-mapping>
<servlet>
??? <servlet-name>login</servlet-name>
??? <servlet-class>myservlet.control.HandleLogin</servlet-class>
</servlet>
<servlet-mapping>
?? <servlet-name>login</servlet-name>
?? <url-pattern>/helpLogin</url-pattern>
</servlet-mapping>
? 數據庫設計與連接
?? 1? 創建一個數據庫 、表??
使用MySQL建立一個數據庫student,該庫共有一個user表 。
??? user表的用途:存儲用戶的注冊信息。即會員的注冊信息存入user表中,user表的主鍵是logname,各個字段值的說明如下:
logname :存儲注冊的用戶名(屬性是字符型,主鍵)。
password :存儲密碼(屬性是字符型)。
email :存儲email(屬性是字符型)。?????
2? 數據庫連接
??? 避免操作數據庫出現中文亂碼,需要使用
????? Connection getConnection(java.lang.String) 方法建立連接,連接中的代碼是(用戶是root,其密碼是空):
?String url = "jdbc:mysql://127.0.0.1/student?"+
???????????? "user=root&password=&characterEncoding=gb2312";
Connection con = DriverManager.getConnection(uri);