1. 程式人生 > >伺服器端程式設計完整例項

伺服器端程式設計完整例項

專案結構


下面對每個包對應的邏輯和功能做簡要說明

com.bupt.dao:裡面是進行資料庫操作的相關介面。介面相當於一種規範,增加了系統的可測試性和健壯性,無論之後的daoImpl中的實現程式碼如何改變,只要介面不改變就不會影響程式的執行,降低了程式的耦合度,便於進行單元測試。

com.bupt.dao.impl:裡面是上面資料庫相關操作介面的實現類。

com.bupt.entity:裡面是要在資料庫中操作的物件實體,比如使用者物件,可以看作資料庫中的一張表,使用者表或是地址表之類的。他們在資料庫中所在的表不同,但是都有一個主鍵id(userId,addressId...),所以他們要統一的繼承抽象類IdEntity,這個類裡只有一個id,專案的邏輯更加清晰,程式碼更少。

com.bupt.service:裡面是根據專案的要求不同進行的一些服務操作,比如判斷使用者表中有沒有重複的使用者名稱之類的。儘管UserDaoImpl中,我們也可以寫相應的實現方法,但是這個服務層是有存在的意義的,如果沒有這個服務層,那麼servlet就要直接呼叫UserDaoImpl中的方法,但是UserDaoImpl中的方法只是執行了資料庫的查詢或是插入操作,如果有更加複雜的操作,那麼就無法滿足,強行滿足要求就要在impl類中寫大量複雜的實現,而且servlet中就要多次呼叫daoImpl中的方法,導致servlet無法明顯的體現出自身要執行的功能,這樣模糊的servlet可能就要導致客戶端執行一個註冊功能就要多次請求不同的servlet來完成,所以service層的存在使得整個專案的層次更加清晰。

com.bupt.servlet:裡面是客戶端進行相應請求要訪問的servlet類。

com.bupt.util:裡面是連線資料庫所需的ConnectionFactory工廠類,其中的dburl等引數是從配置檔案dbconfig.properties中讀取的。需要jdbc的jar包,複製進來並引用。

下面貼程式碼

UsreDao

package com.bupt.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.bupt.entity.User;

//資料庫中使用者表相關的操作介面

public interface UserDao {
	public void insert(Connection conn, User user) throws SQLException;

	public ResultSet get(Connection conn, User user) throws SQLException;
}

UserDaoImpl
package com.bupt.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.bupt.dao.UserDao;
import com.bupt.entity.User;

//資料庫中有關使用者表的介面實現

public class UserDaoImpl implements UserDao {

	@Override
	public void insert(Connection conn, User user) throws SQLException {
		String sql = "INSERT INTO user(username,password,email) VALUES (?,?,?)";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, user.getUserName());
		ps.setString(2, user.getPassword());
		ps.setString(3, user.getEmail());
		ps.execute();
	}

	@Override
	public ResultSet get(Connection conn, User user) throws SQLException {
		String sql = "SELECT * FORM user WHERE username=?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, user.getUserName());
		return ps.executeQuery();
	}

}

IdEntity
package com.bupt.entity;

//Id實體抽象類,其他實體類的父類

public abstract class IdEntity {
	private Long id;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
	
}

User
package com.bupt.entity;

//使用者實體,因為之後每個實體在資料表中都有主鍵id屬性,所以他們都繼承了IdEntity抽象類

public class User extends IdEntity {

	private String userName;
	private String password;
	private String email;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}

CheckUserPermissionService
package com.bupt.service;

import java.sql.Connection;
import java.sql.ResultSet;

import com.bupt.dao.UserDao;
import com.bupt.dao.impl.UserDaoImpl;
import com.bupt.entity.User;
import com.bupt.util.ConnectionFactory;

//驗證使用者登入是否成功
//有三個不同的返回情況

//return 1:登入成功
//return 2:密碼錯誤
//return 3:無此使用者

public class CheckUserPermissionService {
	public static int checkPermission(User user) {
		Connection conn = null;
		boolean hasUser = false;
		try {
			UserDao us = new UserDaoImpl();
			conn = ConnectionFactory.getInstance().makeConnection();
			conn.setAutoCommit(false);
			ResultSet rs = us.get(conn, user);
			if (rs.next()) {
				hasUser = true;
				if(user.getPassword().equals(rs.getString("password"))){
					return 1;
				}
			}
			if(hasUser == true){
				return 2;
			}
		} catch (Exception e) {
			e.printStackTrace();
			try {
				conn.rollback();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		} finally {
			try {
				conn.close();
			} catch (Exception e3) {
				e3.printStackTrace();
			}
		}
		return 3;
	}
}

CheckUserService
package com.bupt.service;

import java.sql.Connection;
import java.sql.ResultSet;

import com.bupt.dao.UserDao;
import com.bupt.dao.impl.UserDaoImpl;
import com.bupt.entity.User;
import com.bupt.util.ConnectionFactory;

//查詢資料庫使用者表中有沒有相同的使用者名稱

public class CheckUserService {
	public static boolean check(User user) {
		Connection conn = null;
		try {
			UserDao us = new UserDaoImpl();
			conn = ConnectionFactory.getInstance().makeConnection();
			conn.setAutoCommit(false);
			ResultSet rs = us.get(conn, user);
			if (rs.next()) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			try {
				conn.rollback();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		} finally {
			try {
				conn.close();
			} catch (Exception e3) {
				e3.printStackTrace();
			}
		}
		return false;
	}
}

InsertUserService
package com.bupt.service;

import java.sql.Connection;

import com.bupt.dao.UserDao;
import com.bupt.dao.impl.UserDaoImpl;
import com.bupt.entity.User;
import com.bupt.util.ConnectionFactory;

//將建立好的實體使用者插入到資料庫中
/*
 * 儘管UserDaoImpl中也有相應的插入資料的實現方法,但是這個服務類有存在的意義,
 * 如果沒有這個服務類,那麼servlet就要直接呼叫UserDaoImpl中的方法,
 * 但是UserDaoImpl中的方法只是執行了資料庫的查詢或是插入操作,如果有更加複雜的操作,那麼就無法滿足,
 * servlet中就要多次呼叫daoImpl中的方法,導致servlet無法明顯的體現出自身要執行的功能,
 * 這樣模糊的servlet可能就要導致客戶端執行一個註冊功能就要多次請求不同的servlet來完成,
 * 所以service層使得整個專案的層次更加清晰
*/

public class InsertUserService {
	public static void insert(User user) {
		Connection conn = null;
		try {
			UserDao us = new UserDaoImpl();
			conn = ConnectionFactory.getInstance().makeConnection();
			conn.setAutoCommit(false);
			us.insert(conn, user);
			System.out.println("插入新使用者成功");
		} catch (Exception e) {
			e.printStackTrace();
			try {
				conn.rollback();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		} finally {
			try {
				conn.close();
			} catch (Exception e3) {
				e3.printStackTrace();
			}
		}
	}
}

LoginServlet
package com.bupt.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bupt.entity.User;
import com.bupt.service.CheckUserPermissionService;

//客戶端進行登入時要請求的servlet
//url-pattern: /login

//login success:登入成功
//password error:密碼錯誤
//no user:無此使用者

public class LoginServlet extends HttpServlet {

	private static final long serialVersionUID = 5290609484927130100L;

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String userName = req.getParameter("username");
		String password = req.getParameter("password");

		User user = new User();
		user.setUserName(userName);
		user.setPassword(password);

		int result = CheckUserPermissionService.checkPermission(user);
		PrintWriter pw = resp.getWriter();

		if (result == 1) {
			pw.print("login success");
		} else if (result == 2) {
			pw.print("password error");
		} else {
			pw.print("no user");
		}
		pw.close();
	}

}

RegisterServlet
package com.bupt.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bupt.entity.User;
import com.bupt.service.CheckUserService;
import com.bupt.service.InsertUserService;

//客戶端進行註冊時要請求的servlet
//url-pattern: /register

//"register success":註冊成功
//"username repeat":使用者名稱重複

public class RegisterServlet extends HttpServlet {

	private static final long serialVersionUID = 3971678149369992198L;

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String userName = req.getParameter("username");
		String password = req.getParameter("password");
		String email = req.getParameter("email");

		User user = new User();
		user.setUserName(userName);
		user.setPassword(password);
		user.setEmail(email);

		boolean flag = CheckUserService.check(user);
		PrintWriter pw = resp.getWriter();
		if (flag == false) {
			InsertUserService.insert(user);
			pw.println("register success");
		} else {
			pw.print("username repeat");
		}
		pw.close();
	}

}

ConnectionFactory
package com.bupt.util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

//提供資料庫連線的連線工廠類,driver,dburl,user,password等屬性由dbconfig.properties得到

public class ConnectionFactory {

	private static String driver;
	private static String dburl;
	private static String user;
	private static String password;

	private static final ConnectionFactory factory = new ConnectionFactory();
	private Connection conn;

	static {
		Properties prop = new Properties();
		try {
			InputStream inputStream = ConnectionFactory.class.getClassLoader()
					.getResourceAsStream("dbconfig.properties");
			prop.load(inputStream);
		} catch (Exception e) {
			e.printStackTrace();
		}
		driver = prop.getProperty("driver");
		dburl = prop.getProperty("dburl");
		user = prop.getProperty("user");
		password = prop.getProperty("password");
	}

	public ConnectionFactory() {

	}

	public static ConnectionFactory getInstance() {
		return factory;
	}

	public Connection makeConnection() {
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(dburl, user, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}

}

dbconfig.properties
driver=com.mysql.jdbc.Driver
dburl=jdbc\:mysql\://localhost\:3306/study?useSSL=false
user=root
password=root

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Study</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>login</servlet-name>
	<servlet-class>com.bupt.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>login</servlet-name>
	<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
	<servlet-name>register</servlet-name>
	<servlet-class>com.bupt.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>register</servlet-name>
	<url-pattern>/register</url-pattern>
</servlet-mapping>
  
  
</web-app>