java 4层架构_java web 分层之—5层架构

JSP 表现层---》Dispatch 分发请求--》Command 交互层---》service 业务逻辑层---》Dao 数据访问层---》数据库

4dd548bb0dc64db211f8af47b03cc822.png

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

表现层:index.jsp

Insert title here

function doSubmit() {

var username = document.getElementById("username").value;

var password = document.getElementById("password").value;

if (username == "" || password == "") {

//alert("用户名和密码不能为空!");

document.getElementById("tips").innerHTML="用户名和密码不能为空!";

} else {

document.loginForm.submit();

}

}

用户名:

密码:

web.xml配置:

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">

dispatch

tool.Dispatch

dispatch

*.do

分发器: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;

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {

//设置编码

req.setCharacterEncoding("GBK");

//解析请求的url

StringBuffer url = req.getRequestURL();

//http://localhost:8080/test4/UserCommand.do

int 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> threadLocal = new ThreadLocal>();

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 localMap = new HashMap();

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 objPool = new HashMap();

/*

* 根据类的包路径名称,返回该类的一个实例。

*/

public static 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 threadLocalCon = new ThreadLocal();

/*

* 获取数据库连接

*/

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 DataSource

url=jdbc:oracle:thin:@localhost:1521:loushang

driver=oracle.jdbc.driver.OracleDriver

username=apitest

password=apitest

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值