J2EE开发 MVC 以OA系统为例

第一次试着以规范的MVVC设计模式写了OA部分的功能。写完以后,对MVC这种著名的设计模式有了一些具体的理解和心得体会。

MVC百度百科如是说:

        MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

       将模型(model)-视图(view)-控制器(controller)三层分离,实现层与层之间尽可能低的耦合性,利于框架的维护与扩展。牺牲了性能,换取了系统弹性。所谓系统弹性,就是怎么搞也搞不跨的性能。

       在经典的J2EE中:

      1.jsp在View层接收用户的操作,如提交表单等。收到请求后,调用controller层的servelt来处理这个request。

      2.servelt调用业务逻辑层service中的方法来处理这个请求。

      3.javabean则为封装了数据实体的对象,每实例化一个javabean,则可理解为创建了一个和数据库中表里一张数据对应的一个对象。在dao层中通过连接数据库,实现具体的数据访问操作,如连接、增、删、改、查等等。

      4.在看过了网上的一些源码和别人写的一些DEMO后,在分包的时候,javabean所在的包名可以叫做 domain(域模型),entity(实体),bean。在过去搞安卓应用开发的时候,我多用entity,在J2EE中,现在看来,更适合于管理数据实体javabean的domain层。

      关于MVC模式的项目中分包名的概述。

        M:代表model,可以理解为javaBean;
        V:代表view,可以理解为jsp;
        c:代表controller,可以理解为action;
       1.domain:这一层是用来管理javaBean实体对象的;
       2.dao:数据访问层,对数据库进行访问;
       3.service:业务逻辑层,通过调用dao层来对数据库进行访问;
       4.web:数据显示层;

接下来,以最近写的OA系统为例,逐步分析这个最简单的DEMO中体现的MVC设计。

——————————————————————————————————————————————————————————————————————————


首先是工程包结构:

       

整个工程分为5块

1.controller:控制层,包含servelt,负责接收用户响应以及回复给用户结果视图。

2.dao:数据访问层。在dao层中首先定义了接口(UsersDao),并在其中分出impl包,实现dao中的接口,连接数据库,并实现基本的数据操作。在本OA系统中,即为用户是否可以成功登陆。

3.service业务逻辑层。在OA系统中,业务逻辑较为简单,就是登录。但在一些大型的如电商或是企业管理系统中,业务逻辑可能会比较复杂,如积分会员,获取详情等等。

4.domain域模型层,此层中包含对javabean实体对象的管理,在OA系统中,需要的实体对象只有一个(Users,请无视那个无关的Books)

5.util公用方法层,在OA系统中,我只写了连接数据库的相关操作。获取连接对象,增删改查,执行SQL语句等。还可以补充一个获取系统时间的util。

其他:那个Test层是开发调试过程中,用来测试数据库连接是否正常,增删改查是否成功执行等。


接下来看各层的类定义与实现。

首先是dao层。

UsersDao是一个接口,定义了数据访问中需要实现的方法。

package com.kyy.dao;

import com.kyy.domain.Users;

public interface UsersDao {
	
	public Boolean isLogin(Users user);

}


UsersDaoImpl是这个接口的实现。

package com.kyy.dao.impl;

import java.sql.SQLException;

import com.kyy.dao.UsersDao;
import com.kyy.domain.Users;
import com.kyy.util.DBHelp;

public class UsersDaoImpl implements UsersDao {

	@Override
	public Boolean isLogin(Users user) {
		// TODO Auto-generated method stub
		boolean ret=false;
		String sql="select * from users where name='%s' and pwd='%s'";
		try {
			if(DBHelp.dbQuery(String.format(sql, user.getName(),user.getPwd())).next()) {
				ret=true;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}
}

接着是业务逻辑service层。因为本OA系统中数据访问中的方法 是否能成功登陆与业务逻辑层中的是否能登陆一样,在业务逻辑层的接口实现中,只需要实例化一个Dao对象,并调用Dao层中方法即可。

UsersService.java

package com.kyy.service;

import com.kyy.domain.Users;

public interface UserService {

	public boolean isLogin(Users User);
}

UsersServiceImpl.java

package com.kyy.service.impl;

import com.kyy.dao.UsersDao;
import com.kyy.dao.impl.UsersDaoImpl;
import com.kyy.domain.Users;
import com.kyy.service.UserService;

public class UsersServiceImpl implements UserService{

	UsersDao dao=new UsersDaoImpl();
	@Override
	public boolean isLogin(Users User) {
		// TODO Auto-generated method stub
		return dao.isLogin(User);
	}
}

最后是控制层controller

通过servelt接受用户的action,并转交给业务逻辑service层来处理

UsersAction.java

package com.kyy.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.kyy.domain.Users;
import com.kyy.service.UserService;
import com.kyy.service.impl.UsersServiceImpl;

/**
 * Servlet implementation class MainMall
 */
public class UsersAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public UsersAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		//this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//doGet(request, response);
		String name=request.getParameter("name");
		String pwd=request.getParameter("pwd");
		Users loginuser=new Users();
		loginuser.setName(name);
		loginuser.setPwd(pwd);
		UserService service=new UsersServiceImpl();
		PrintWriter out=response.getWriter();
		if(service.isLogin(loginuser)) {
			//getServletContext().getRequestDispatcher("mainmall.jsp").forward(request, response);
			out.println("YES!");
		}else {
			//getServletContext().getRequestDispatcher("index.jsp").forward(request, response);
			out.println("NO!");
		}
	}
}

在实现一个servelt后,记得在web.xml中实现对servlet的注册配置以及路由映射。


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>bookshop</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
<servlet>
<servlet-name>UsersAction</servlet-name>
<servlet-class>com.kyy.controller.UsersAction</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>UsersAction</servlet-name>
<url-pattern>/UsersAction.do</url-pattern>
</servlet-mapping> 
</web-app>

在util包中封装关于数据库的连接以及操作。

DBHelp.java

package com.kyy.util;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

public class DBHelp {
	private static final String DRIVER = "com.mysql.jdbc.Driver"; 
	private static final String URL="jdbc:mysql://xx.xx.xx.xxx:xxxx/xxxxxxxxx";
	private static final String PASSWORD="xxxxxxxxxx";
	private static final String USER="xxxx";
	
	public static Connection getConnection() {
        Connection conn = null;
        try {
            Class.forName(DRIVER); // 加载数据库驱动
            if (null == conn) {
                conn = (Connection) DriverManager.getConnection(URL, USER, PASSWORD);
            }
        } catch (ClassNotFoundException e) {
            System.out.println("Sorry,can't find the Driver!");
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    } 
	
	public static int executeNonQuery(String sql) {
        int result = 0;
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = getConnection();
            stmt = (Statement) conn.createStatement();
            result = stmt.executeUpdate(sql);
        } catch (SQLException err) {
            err.printStackTrace();
            free(null, stmt, conn);
        } finally {
            free(null, stmt, conn);
        }
        return result;
    } 
	
	public static ResultSet dbQuery(String sql) {   
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs=null;
        try {  
                conn = getConnection(); 
                stmt = (Statement) conn.createStatement();  
                rs = stmt.executeQuery(sql);  
        } catch (SQLException sqlex) {  
            System.out.println("数据库查询异常:");  
            sqlex.printStackTrace(); 
            free(null,stmt,conn);
        }
        return rs;  
    }  
	
	 public static int dbUpdate(String sql) {  
		 	Connection conn = null;
	        Statement stmt = null;
	        int rs=0;
	        try {  
	                conn = getConnection(); 
	                stmt = (Statement) conn.createStatement(); 
	            //System.out.println("更新语句..."+sql);  
	                rs = stmt.executeUpdate(sql);  
	        } catch (SQLException sqlex) {  
	            System.out.println("数据库更新异常:");  
	            sqlex.printStackTrace();  
	            free(null,stmt,conn);
	        }finally {
	        	free(null,stmt,conn);
			}
	        return rs;  
	    }  
	
	 
	public static void free(ResultSet rs) {
	        try {
	            if (rs != null) {
	                rs.close();
	            }
	        } catch (SQLException err) {
	            err.printStackTrace();
	        }
	 }

	 public static void free(Statement st) {
	        try {
	            if (st != null) {
	                st.close();
	            }

	        } catch (SQLException err) {
	            err.printStackTrace();
	        }
	  }

	  public static void free(Connection conn) {
	        try {
	            if (conn != null) {
	                conn.close();
	            }
	        } catch (SQLException err) {
	            err.printStackTrace();
	        }
	  }

	  public static void free(ResultSet rs, Statement stmt, Connection conn) {
	        free(rs);
	        free(stmt);
	        free(conn);
	  } 
}

最后是负责用户界面view的jsp视图

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>bookshop</title>
	</head>
	<body>
		<form action="UsersAction.do" method="post">
			<p>用户名: <input type="text" name="name" /></p>
  			<p>密码: <input type="text" name="pwd" /></p>
  			<input type="submit" value="Submit" />
		</form>
	</body>
</html>

数据库中的表信息如下

运行结果如下

当输入正确的用户名和密码时

结果如下



当输入错误的用户名和密码时

结果


最后用C#写的HTTP测试工具测试一下


可以看到 Body里的Yes


此外,我并没有重写servelt里的doget方法,所以,直接通过访问网页,执行get请求时无任何返回。


至此,整个OA模块的功能都被打通了。以此文为记,作为从Android移动端转向J2EE WEB开发的新起点。


(要是明年能给宝宝个开发岗的实习就好了~~~~~~)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值