首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

java web 分层之—五层架构

2012-07-04 
java web 分层之—5层架构JSP 表现层---》Dispatch 分发请求--》Command 交互层---》service 业务逻辑层---》Da

java web 分层之—5层架构

JSP 表现层---》Dispatch 分发请求--》Command 交互层---》service 业务逻辑层---》Dao 数据访问层---》数据库
java web 分层之—五层架构

上图为demo程序的总体结构,其中framework包下是“框架”程序,二次开发人员无须改动。?
??

表现层:index.jsp

<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"><title>Insert title here</title><script type="text/javascript">function doSubmit() {var username = document.getElementById("username").value;var password = document.getElementById("password").value;if (username == "" || password == "") {//alert("用户名和密码不能为空!");document.getElementById("tips").innerHTML="<font color='red'>用户名和密码不能为空!</span>";} else {document.loginForm.submit();}}</script></head><body><span id="tips"></span><form name="loginForm" action="user.cmd.UserCommand.do?method=login" method="post">用户名:<input type="text" id="username" name="username" >密码:<input type="password" id="password" name="password" ><input type="button" value="提交" onclick="doSubmit()"></form></body></html>

?

web.xml配置:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"> ?? <servlet>?? <servlet-name>dispatch</servlet-name>?? <servlet-class>tool.Dispatch</servlet-class>?? </servlet>?? ?? <servlet-mapping>?? <servlet-name>dispatch</servlet-name>?? <url-pattern>*.do</url-pattern>?? </servlet-mapping></web-app>

?

分发器:Dispatch.java,拦截所有.do结尾的请求,并将请求转发给相应的cmd进行处理。

package framework.dispatch;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import framework.context.CommandContext;import framework.factory.InstanceFactory;public class Dispatch extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {//设置编码req.setCharacterEncoding("GBK");//解析请求的urlStringBuffer url = req.getRequestURL();//http://localhost:8080/test4/UserCommand.doint a = url.lastIndexOf("/");int b = url.lastIndexOf(".do");//获取请求的cmd的类名(含包路径)String cmdName = url.substring(a + 1, b);//substring(begin(含),end(不含)),即[)try {//获取请求的cmd的实例Object cmdObj = InstanceFactory.getInstance(cmdName);//设置Command上下文信息,放于线程变量中。CommandContext.init(req, resp, getServletContext(), getServletConfig());//获取请求的方法名String methodName = req.getParameter("method");//执行请求的方法,cmd层的方法Method realMehood = cmdObj.getClass().getMethod(methodName);String forwardPath = realMehood.invoke(cmdObj).toString();//执行完毕,进行页面跳转if(forwardPath != null){req.getRequestDispatcher(forwardPath).forward(req, resp);}} catch (IllegalAccessException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} }}

?

??
CommandContext,以线程变量的方式存储当前线程的request、response、servletcontext、servletconfig对象。

package framework.context;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletConfig;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CommandContext {private static ThreadLocal<Map<String,Object>> threadLocal = new ThreadLocal<Map<String,Object>>();private static final String HTTP_SERVLET_REQUEST = "1";private static final String HTTP_SERVLET_RESPONSE = "2";private static final String SERVLET_CONTEXT = "3";private static final String SERVLET_CONFIG = "4";/* * 初始化线程局部变量 */public static void init(HttpServletRequest req,HttpServletResponse resp,ServletContext context,ServletConfig config){threadLocal.remove();Map<String,Object> localMap = new HashMap<String, Object>();localMap.put(HTTP_SERVLET_REQUEST, req);localMap.put(HTTP_SERVLET_RESPONSE, resp);localMap.put(SERVLET_CONTEXT, context);localMap.put(SERVLET_CONFIG, config);threadLocal.set(localMap);}/* * 获取request对象 */public static HttpServletRequest getRequest(){return (HttpServletRequest)threadLocal.get().get(HTTP_SERVLET_REQUEST);}/* * 获取response对象 */public static HttpServletResponse getResponse(){return (HttpServletResponse)threadLocal.get().get(HTTP_SERVLET_RESPONSE);}/* * 获取servletContext对象 */public static ServletContext getServletContext(){return (ServletContext)threadLocal.get().get(SERVLET_CONTEXT);}/* * 获取servletConfig对象 */public static ServletConfig getServletConfig(){return (ServletConfig)threadLocal.get().get(SERVLET_CONFIG);}}

??

?? command交互层:

package user.cmd;import framework.context.CommandContext;import framework.factory.InstanceFactory;import user.service.UserService;public class UserCommand {UserService userService = InstanceFactory.getInstance(UserService.class.getName());/* * 执行登录验证 */public String login(){String username = CommandContext.getRequest().getParameter("username");String password = CommandContext.getRequest().getParameter("password");//调用service层boolean isOk = userService.checkLogin(username, password);if(isOk){return "ok.jsp";}return "fail.jsp";}}

?

??

service层:UserService.java

package user.service;import framework.db.TransactionManager;import framework.factory.InstanceFactory;import user.dao.UserDao;public class UserService {UserDao dao = InstanceFactory.getInstance(UserDao.class.getName());/* * 执行登录验证 */public boolean checkLogin(String username, String password) {if (password == null) {return false;}String pass = null;//拿到事务管理器TransactionManager tm = TransactionManager.getTransManager();try {//开启事务tm.beginTransaction();pass = dao.getPassword(username);//提交事务tm.commitTransaction();} catch (RuntimeException e) {e.printStackTrace();tm.rollbackTransaction();//出现异常则回滚事务}if (password.equals(pass)) {return true;} else {return false;}}}

?

?

?

Dao层:

package user.dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import framework.db.DBUtil;//--创建表 T_USERS//CREATE TABLE T_USERS(//    USERNAME VARCHAR2(10) NOT NULL,//    PASSWORD VARCHAR2(60) NOT NULL//);//--设置主键//ALTER TABLE T_USERS ADD CONSTRAINT T_USERS_PK PRIMARY KEY(USERNAME);public class UserDao {/* * 根据用户名,查询密码 */public String getPassword(String username){String pass = null;Connection conn = null;PreparedStatement ps = null;ResultSet set = null;try{conn = DBUtil.getCon();ps = conn.prepareStatement("select password from t_users where username=?");ps.setString(1, username);set = ps.executeQuery();if (set.next()){pass = set.getString("PASSWORD");}} catch (SQLException e) {throw new RuntimeException("根据用户名查询密码出错",e);}finally{DBUtil.close(set, ps, conn);}return pass;}}

?

?

实例工厂类:

package framework.factory;import java.util.HashMap;import java.util.Map;/* * 实例工厂类,用于统一管理cmd、service、dao的实例。 */public class InstanceFactory {//创建一个对象池private static Map<String,Object> objPool = new HashMap<String, Object>();/* * 根据类的包路径名称,返回该类的一个实例。 */public static <T> T getInstance(String clazz){T obj = null;if(objPool.containsKey(clazz)){//如果对象池中已存在,则直接从对象池中获取。obj = (T)objPool.get(clazz);}else{try {//如果对象池中不存在,则动态创建一个该类的实例,并将新创建的实例放入对象池。obj =  (T)Class.forName(clazz).newInstance();objPool.put(clazz, obj);} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}return obj;}}

?

TransactionManager 事务管理器

package framework.db;import java.sql.Connection;import java.sql.SQLException;public class TransactionManager {private Connection con;private TransactionManager(Connection con){this.con = con;}/* * 开启事务 */public void beginTransaction(){try {con.setAutoCommit(false);} catch (SQLException e) {throw new RuntimeException("开启事务失败!",e);}}/* * 提交事务 */public void commitTransaction(){try {con.commit();} catch (SQLException e) {throw new RuntimeException("提交事务失败!",e);}finally{closeConnection();DBUtil.threadLocalCon.remove();//将数据库连接从线程局部变量中卸载。}}/* * 回滚事务 */public void rollbackTransaction(){try {con.rollback();} catch (SQLException e) {throw new RuntimeException("回滚事务失败!",e);}finally{closeConnection();DBUtil.threadLocalCon.remove();//将数据库连接从线程局部变量中卸载。}}/* * 获取事务管理器 */public static TransactionManager getTransManager(){return new TransactionManager(DBUtil.getCon());}/* * 关闭数据库连接,仅限事务管理器内部使用,故private */private void closeConnection(){if(con != null){try {con.close();} catch (SQLException e) {e.printStackTrace();}}}}

?

?

?DBUtil ,用于获取数据库连接和关闭连接

package framework.db;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;public class DBUtil {private static String url = null;private static String driver = null;private static String username = null;private static String password = null;static{Properties p = new Properties();//加载数据源配置文件InputStream inputStream = null;try {inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dataSource.properties");p.load(inputStream);url = p.getProperty("url");driver = p.getProperty("driver");username = p.getProperty("username");password = p.getProperty("password");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}//线程局部变量protected static ThreadLocal<Connection>  threadLocalCon = new ThreadLocal<Connection>();/* * 获取数据库连接 */public static Connection getCon() {Connection con = threadLocalCon.get();try {if (con == null || con.isClosed()) {Class.forName(driver);con = DriverManager.getConnection(url, username, password);threadLocalCon.set(con);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return con;}/* * 关闭结果集 ResultSet */public static void closeResultSet(ResultSet rs){if(rs != null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}}/* * 关闭 句柄 */public static void closeStatement(Statement st){if(st != null){try {st.close();} catch (SQLException e) {e.printStackTrace();}}}/* * 在事务中调用dao层方法时,会首先设置事务自动提交为false,该场景下,关闭连接由事务管理器负责。 * 如果dao层方法没有在事务中执行,则此时事务自动提交为true,该场景下,由本方法负责关闭连接。 */public static void closeConnectionIfAutoCommit(Connection con){if(con != null){try {if(con.getAutoCommit()){con.close();}} catch (SQLException e) {e.printStackTrace();}}}/* * 依次关闭ResultSet、Statement、Connection */public static void close(ResultSet rs,Statement st,Connection con){closeResultSet(rs);closeStatement(st);closeConnectionIfAutoCommit(con);}}

?

?

dataSource.properties配置文件

#Oracle DataSourceurl=jdbc:oracle:thin:@localhost:1521:loushangdriver=oracle.jdbc.driver.OracleDriverusername=apitestpassword=apitest

?

?

热点排行