掌握Model I的开发原理
掌握Mode II 的开发原理
两种开发模式为整个WEB 的核心操作,其中以模式二 最为重要,可以这么说,如果可以将模式而 彻底的掌握了。
Mode I
1、Mode I 就是指在开发中讲显示层、控制层、数据层的操作统一交给JSP 或者是JavaBean来进行处理
客户端 [ (<——response )(request ——>)] <————> JSP <————>JavaBean <————>数据库
之前的的JavaB的DAO设计模式,实际上在这道程序中可以发现,DAO负责完成数据层的操作,而JSP 负责显示,一个典型的JSP + JavaBean 的开发模式
客户端现在通过访问的Jsp , 调用里面的JavaBean, 而通过JavaBean调用数据库
在JavaBean 中就包含了有专门负责处理数据的操作,数据层主要是以DAO为主,除了数据之外还包含了业务的处理。
在整个的开发中本身就存在了一个问题,现在的程序肯定是需要JSP + JavaBean 一起开发完成后才可以使用,此时就可能出现推诿的问题,例如: 美工同志说了,程序必须先写成,我再作美工,程序员说了,你必须先做美工我再写程序,所以,这种的开发本身只适合与较快速的开发,但是后期维护困难,可以发现这种开发之后的代码在JSP文件之中的, Scriptlet代码非常多。
Mode II: Model - View -Controller (mvc)
在Mode II 中所以的开发都是以Servlet为主体展开的,由Servlet 接收所有的客户端请求,之后根据请求调用相应的JavaBean, 并将所有的显示结果交给JSP完成,也就是俗称的MVC设计模式
Servlet特点: 可以接收用户的请求参数,环科院调用 java程序,而且由于本身就是以java 程序运行的,所以肯定要比JSP性能高很多的,而且安全性也高
最终Servlet 所以操作的内容都要交给JSP进行显示,这样一来,Servlet 的缺点就避免了
JavaBean 完成具体的单个的功能: JSP完成显示的功能,而Servlet负责连接JSP和JavaBean
JSP ————> Servlet ————> JavaBean 。 这种设计非常适合于大型的项目开发,而且维护方便
MVC有自己的处理流程,实际上最重要的就是输出和跳转的问题了
而且一定要再次强调,由于所有的内容都是要交给JSP进行显示,那么这个时候最方便的属性范围就是request 属性范围,例如: 以一个雇员列表操作为例,可以发现,JSP中只是负责显示一次即可,而且Servlet 应该负责将所有的一次显示的内容交给JSP 完成,那么最合适的属性范围就是request 范围了,因为之前强调过,能用page(pageContext) 就不要使用request ,能用request 就不要使用session ,能使用session 就不要使用application
从实际的开发来讲, session 属性范围用于登录验证上使用较多,而request 范围主要的功能就是在MVC 设计模式上,将Servlet 的内容交给JSP显示,而且这种显示在另外一次提交之后属性就消失了。
本章目标
掌握MVC 在实际开发中的应用
掌握MVC完成一个用户登录程序的开发
内容
登录程序之前已经学习过,是使用JSP + JDBC完成的开发操作, 但是之前的登录程序开发中可以发现有很多问题,就是一个JSP 文件中代码过多了,即便是使用了JSP + JavaBean 的开发模式,其本身也存在JSP 中代码过多的问题
现在就可以利用MVC设计模式来彻底解决掉这些代码过多的问题了
在本程序中用户登录信息提交给Servlet 进行接收,Servlet 接收到请求内容后首先对其合法性进行校验(例如: 输入的内容是否为空或者长度是否满足要求等),如果验证失败,则将错误信息传递给登录页显示,如果数据合法,则调用DAO 层完成数据库的验证,根据验证的结构跳转到“登录成功” 或登录失败的页面,在本程序中,为了操作便捷,将登录成功或失败的显示页都统一设置成登录页。
- use mydata;
- drop table user;
- create table user(
- userid varchar(30) primary key,
- name varchar(30) not null,
- password varchar(30) not null
- );
- insert into user(userid,name,password) values ('admin','tom','admin');
只要有异常一定要交给被调用处进行处理
数据库创建脚本完成之后,那么下面就开始进行程序的开发操作了
DAO的操作注意是完成数据层的操作,但是下面在MVC设计模式之中,还有Servlet 也很重要,建立一个LoginServlet.java的操作类
在MVC开发中注意,客户端验证和服务器端的验证都需要进行处理的操作
而且从这道程序中,读者也可以发现这样一个问题,以前的jsp 页面中的代码实在是太多了,但是现在的代码明显比以前少很多,实际上对于一个jsp 页面应该只包含如下的代码
1、通过本MVC程序,读者可以清楚的感觉到,与最初的JSP 开发(例如JSP+JDBC 或者是 JSP+DAO) 相比,现在的JSP 页面中的代码已经减少了很多,只是简单的完成了输出,实际上在开发中,JSP中最好只包含以下三种类型的代码:
接收属性: 接收从Servlet 传递过来的属性
判定语句: 判定传递到JSP 中的属性是否存在
输出内容: 使用迭代或者是VO进行输出
一定要记住一点, 在JSP 页面中唯一允许导入的包只能是java.util 包,只要能把握住这一点,就可以开发出一 个简洁、清晰的JSP 页面
一 个好的页面应该不导入任何一个开发包
明白MVC的实际开发作用,以及:JSP 、Servlet、DAO的各个组成部分的作用。DAO只是负责实际的操作,JSP只是负责显示,Servlet只是负责接收数据,调用JavaBean ,并进行跳转的功能
以下是整个页面程序的代码
- package org.gz.mvc.vo;
- public class User {
- private String userid;
- private String name;
- private String password;
- public void setUserid(String userid) {
- this.userid = userid;
- }
- public void setName(String name) {
- this.name = name;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public String getUserid() {
- return this.userid;
- }
- public String getName() {
- return this.name;
- }
- public String getPassword() {
- return password;
- }
- }
- package org.gz.mvc.dbc;
- import java.sql.*;
- public class DatabaseConnection {
- private static final String DBDRIVER = "org.gjt.mm.mysql.Driver";
- private static final String DBURL = "jdbc:mysql://localhost:3306/mydata";
- private static final String DBUSER = "root";
- private static final String DBPASSWORD = "root";
- private Connection conn = null;
- public DatabaseConnection () throws Exception {
- try
- {
- Class.forName(DBDRIVER);
- this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD);
- }
- catch (Exception e)
- {
- throw e;
- }
- }
- public Connection getConnection () {
- return this.conn;
- }
- public void close() throws Exception {
- if(conn != null) {
- try
- {
- conn.close();
- }
- catch (Exception e)
- {
- throw e;
- }
- }
- }
- }
- package org.gz.mvc.dao;
- import org.gz.mvc.vo.*;
- public interface UserDao {
- //现在完成的的登录验证,那么登录操作只有两种返回结果 (成功|失败)
- public boolean findLogin(User user) throws Exception ;
- }
- package org.gz.mvc.dao.imp;
- import org.gz.mvc.vo.*;
- import org.gz.mvc.dao.*;
- import org.gz.mvc.dbc.*;
- import java.sql.*;
- public class UserDaoImp implements UserDao {
- private Connection conn = null;
- private PreparedStatement pstm = null;
- public UserDaoImp (Connection conn) {
- this.conn = conn;
- }
- //现在完成的的登录验证,那么登录操作只有两种返回结果 (成功|失败)
- public boolean findLogin(User user) throws Exception {
- boolean flag = false;
- String sql = "select name from user where userid=? and password=?";
- this.pstm = this.conn.prepareStatement(sql);
- this.pstm.setString(1,user.getUserid());
- this.pstm.setString(2,user.getPassword());
- ResultSet rs = pstm.executeQuery();
- if(rs.next()) {
- user.setName(rs.getString(1)); //取出一个用户名的真实姓名
- flag = true;
- }
- this.pstm.close();
- return flag;
- }
- }
- package org.gz.mvc.dao.proxy;
- import org.gz.mvc.vo.*;
- import org.gz.mvc.dao.*;
- import org.gz.mvc.dao.imp.*;
- import org.gz.mvc.dbc.*;
- import java.sql.*;
- // 代理类的主要功能是负责关闭
- public class UserDaoProxy implements UserDao {
- private DatabaseConnection dbc = null;
- private UserDao dao = null;
- public UserDaoProxy () {
- try
- {
- this.dbc = new DatabaseConnection();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- this.dao = new UserDaoImp(dbc.getConnection());
- }
- //现在完成的的登录验证,那么登录操作只有两种返回结果 (成功|失败)
- public boolean findLogin(User user) throws Exception {
- boolean flag = false;
- try
- {
- flag = this.dao.findLogin(user); //调用真实主题完成操作
- }
- catch (Exception e)
- {
- throw e;
- } finally {
- this.dbc.close();
- }
- return flag;
- }
- }
- package org.gz.mvc.factory;
- import org.gz.mvc.dao.*;
- import org.gz.mvc.dao.proxy.*;
- public class UserDaoFactory {
- public static UserDao getUserDaoInstance() {
- return new UserDaoProxy();
- }
- }
- package org.gz.mvc.servlet;
- import java.util.*;
- import java.io.*;
- import javax.servlet.*;
- import javax.servlet.http.*;
- import org.gz.mvc.factory.*;
- import org.gz.mvc.vo.*;
- public class LoginServlet extends HttpServlet {
- public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException ,IOException {
- String path = "login.jsp";
- String userid = req.getParameter("userid");
- String userpass = req.getParameter("userpass");
- List<String> info = new ArrayList<String>(); //收集错误信息
- if(userid == null || "".equals(userid)) {
- info.add("用户id不能为空");
- }
- if(userpass == null || "".equals(userpass)) {
- info.add("密码不能为空");
- }
- if(info.size() == 0) { //里面没有记录任何的错误
- User user = new User();
- user.setUserid(userid);
- user.setPassword(userpass);
- try {
- if(UserDaoFactory.getUserDaoInstance().findLogin(user)) {
- info.add("用户登录成功,欢迎" + user.getName() + "光临");
- } else {
- info.add("用户端登录失败,错误的用户名或密码!");
- }
- } catch (Exception e){
- e.printStackTrace();
- }
- }
- req.setAttribute("info",info);
- req.getRequestDispatcher(path).forward(req,resp);
- }
- public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException ,IOException {
- this.doGet(req,resp);
- }
- }
- <%@ page contentType="text/html" pageEncoding="GBK"%>
- <%@ page import="java.util.*"%>
- <html>
- <head> <title>欢迎光临</title>
- </head>
- <body>
- <script language="javascript">
- function validate(f) {
- if(!(/^\w[5,15]$/.test(f.userid.value))) {
- alert("用户ID必须是5~15!");
- f.userid.focus();
- return false;
- }
- if(/^\w[5,15]$/.test(f.userpass.value)) {
- alert("密码必须是5~15!");
- f.userpass.focus();
- return false;
- }
- }
- </script>
- <%
- request.setCharacterEncoding("GBK");
- %>
- <%
- List<String> info = (List<String>) request.getAttribute("info");
- if(info != null) {
- Iterator<String> iter = info.iterator();
- while(iter.hasNext()) {
- %>
- <h3><%=iter.next()%></h3>
- <%
- }
- }
- %>
- <form action="LoginServlet" method="post" onSubmit="return validate(this)">
- 用户ID: <input type="text" name="userid"><br>
- 密 码: <input type="password" name="userpass"><br>
- <input type="submit" value="登录">
- <input type="reset" value="重置">
- </form>
- </body>
- </html>
- Servlet and JSP Examples.
- </description>
- <servlet>
- <servlet-name>login</servlet-name>
- <servlet-class>org.gz.mvc.servlet.LoginServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>login</servlet-name>
- <url-pattern>/servletdemo/LoginServlet</url-pattern>