Servlet项目之销售合同项目(二)

搭建MVC模型

大家应该都知道MVC(Model View Controller)模型,也就是模型(model)-视图(view)-控制器(controller)
他是最常见的软件架构之一,现在市面上很多模型都是基于MVC,百变不离其宗。

STEP1: View 传送指令到 Controller
STEP2: Controller 完成业务逻辑后,要求 Model 改变状态
STEP3: Model 将新的数据发送到 View,用户得到反馈

在这里插入图片描述
那么根据MVC模型,我们就可以建立相应的功能包了
在这里插入图片描述
这里我来解释以下,bean包主要存放的是JavaBean实体类,比如说User,Customer等
dao层和dao.impl则是直接和数据库打交道的包,因此里面就涉及到JDBC的一系列操作了。
service包和service.impl则是将数据库中查询出来的数据进行处理,比如说数据组装,异常处理等等,形成一个较为完善的功能,这两个包都隶属于Model。
servlet包顾名思义就是存储Servelt类的包了,Servlet也就是连接页面和后台之间的一座桥梁了,因此他存在的意义也非凡,它隶属于Controller层。

那么View层都有些什么呢?view就是给客户看的东西,大家应该可以想到了对吧~
我们的HTML网页就是给客户看的,但是一般使用jsp将页面的内容动态的渲染出来,将jsp和Servlet以及Model层和数据库成功搭建起来,我们的项目才算完成。这里我的项目主要是处理后台,main.jsp为我们的主页面,包含功能菜单,Login登陆验证项目具体可以查看Marco’s Java 之【JSON&AJAX&登陆验证小项目】
在这里插入图片描述

准备工作
其他功能包介绍

Ok,讲了这么多大家可能发现还有几个包不知道是做什么用的,anno,comm和util
anno(Annotation): 存放注解,这个主要是为了结合我写的一套BaseDao中的通用添加数据到数据库使用的,具体可以点击查看文章 Marco’s Java 之【JDBC辅助类封装】
comm(Comment): 存放辅助信息类,这个我们下面再讲
util: 存放工具类

下面是anno(Annotation)的代码,比较简单,一个Column和一个Table,对类和类属性进行注释

@Target(value=ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
	String value() default "";
}
@Target(value=ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table { 
	String value() default "";
}

接下来是util,网上其实有很多工具类,大家也可以根据需求自行封装

/*用于检查元素是否为空,主要用于前后端数据是否为空的校验*/
public class CheckParamUtil {
	
	public static boolean isBlank(Object element) {
		return (element == null) || "".equals(element);
	}
	
	public static String checkEmpty(Map<String,String[]> params , String...keys) {
		for (int i = 0; i < keys.length; i++) {
			String key = keys[i];
			String[] values = params.get(key);
			if(!params.containsKey(key)) {
				return CodeMsg.PARAM_INCOMPLETE.getMessage() + "【"+ key +"】";
			}
			String valueStr = Arrays.toString(values);
			valueStr = valueStr.substring(1,valueStr.length()-1).trim();
			if(valueStr == null || "".equals(valueStr)) {
				return CodeMsg.PARAM_BLANK.getMessage() + "【"+ key +"】";
			}
		}
		
		return null;
	}
}
/*模拟数据库连接池,一般来说小项目其实不需要连接池,但是也是为了模拟使用嘛*/
public class ConnPool {
	private static String driver = null;
	private static String url = null;
	private static String userName = null;
	private static String password = null;
	private final static int MINSIZE = 5;//最小连接数量为5
	private final static int MAXSIZE = 10;//最大连接数量为10
	private static Properties pro = new Properties();
	
	//创建一个线程池,用于存储本地的Connection
	private LinkedList<Connection> connPool = new LinkedList<Connection>();
	//记录当前的连接数量
	private int currentSize = 0;
	//获取操作对象
	public static void main(String[] args) {
		ConnPool cp = new ConnPool();
		System.out.println(cp.getConnection());
		System.out.println(cp.getConnection());
		System.out.println(cp.getConnection());
	}
	//加载驱动
	static {
		try {
			pro.load(ConnPool.class.getClassLoader().getResourceAsStream("config.properties"));
			driver = pro.getProperty("driver");
			url = pro.getProperty("url");
			userName = pro.getProperty("username");
			password = pro.getProperty("password");
			Class.forName(driver);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public ConnPool() {
		for (int i = 0; i < MINSIZE; i++) {
			Connection conn = this.createConn();
			connPool.add(conn);
			currentSize ++;
		}
	}

	//获取连接对象(内部使用)
	private  Connection createConn() {
		Connection conn = null;
		//如果当前线程中没有绑定相应的Connection
		try {								
			conn = DriverManager.getConnection(url, userName, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	public  Connection getConnection() {
		if(connPool.size() > 0) {
			Connection conn = connPool.getFirst();
			connPool.removeFirst();
			return conn;
		} else if(connPool.size()==0 && currentSize< MAXSIZE) {
			currentSize++;
			connPool.addLast(this.getConnection());
			Connection conn = connPool.getFirst();
			connPool.removeFirst();
			return conn;
		}
		throw new RuntimeException("连接数量已经到到达上限,请稍等");
	}
	
	public  void realse(Connection conn) {
		//ThreadLocal取得当前线程的connection
		connPool.add(conn);
	}
	//让当前线程放行
	public static void realse(PreparedStatement ps) {
		if(ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	public  static void realse(ResultSet rs, PreparedStatement ps) {
		if(rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		realse(ps);
	}
}
/*时间工具类,这个工具类的作用有很多,比如说前后端的时间的格式转化,或者生成不重复的数据串*/
public class DateUtil {
	public final static String yyyyMMddHHmmssSSS = "yyyyMMddHHmmssSSS";
	public final static String yyyyMMdd = "yyyy-MM-dd";
	
	
	public static String getDateString(String fomart) {
		Date date = new Date();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fomart);
		return simpleDateFormat.format(date);
	}
	
	public static Date StingToDate(String Date, String dateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Date date = null;
		try {
			date = sdf.parse(Date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static String getDateString(Date date, String fomart) {
		SimpleDateFormat sdf = new SimpleDateFormat(fomart);
		return sdf.format(date);
	}
	
	public static Date addDate(Date date, int num) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, num);
		return calendar.getTime();
	}
	
}
/*这个工具主要是将获取前台的数据的操作简化,并排除非空*/
public class ServletUtil {
	/**
	 * 获取页面的上的参数和值,将其封装到Map集合中
	 * @param request 
	 * @param params
	 * @return Map
	 */
	public static Map<String, Object> putInMap(HttpServletRequest request, String...params) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		for (int i = 0; i < params.length; i++) {
			String paramName = params[i];
			String paramValue = request.getParameter(paramName);
			if(!CheckParamUtil.isBlank(paramValue)) {
				paramMap.put(paramName, request.getParameter(paramName));
			}
		}
		return paramMap;
	}
	/*简化前台信息打印操作*/
	public static void print(Result result, HttpServletResponse response) {
		try {
			response.getWriter().print(result.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

上面的包中的类也比较简单,接下来还有一个包没有讲,就是comm包,这个包中我存放了三个类
准确来说是两个普通类(PageQueryInfo,Result,CodeMsg),一个枚举类
CodeMsg主要是将成功的信息和他的code(这个可以自己随意取,后期可以做成API供阅览)封装起来,便于前台jsp获取解析后台的结果

public enum CodeMsg {
	
	SUCCESS("200","SUCCESS"),
	LOGIN_ERROR("10001","USERNAME OR PASSWORD INCORRECT"),
	PARAM_ERROR("10002","PARAM ECC ERROR "),
	PARAM_BLANK("100021","PARAM CAN'T BE BLANK"),
	PARAM_INCOMPLETE("100022","PARAM IS INCOMPLETE"),
	CHECK_CODE_ERROR("10003","CHECK CODE INCORRECT"),
	DELETE_DATA_FAILED("10004","DELETE FAILED"),
	ADD_DATA_FAILED("10005","ADD FAILED"),
	FILE_UPLOAD_ERROR("20001","FILE UPLOAD FAILED"),
	FILE_UPLOAD_SUCCESS("0","FILE UPLOAD SUCCESS"),
	DATA_NOT_FOUNT("404","DATA NOT FOUND"),
	AVATAR_UPDATE_ERROR("20002","FILE UPDATE FAILED"),
	EDIT_DATA_ERROR("30001","DATA WERE EDIT FAILED"),
	BATCH_UPDATE_ERROR("50001","BATCH UPDATE FAILED"),
	VISITLOG_UPDATE_ERROR("20002","VISITLOG UPLOAD FAILED"),
	ATHORIZE_ROLE_FAILED("60001","ATHORIZE ROLE FAILED");
	
	
	private final String code;
	private final String message;
		
	private CodeMsg(String code, String message) {
		this.code = code;
		this.message = message;
	}
	public String getCode() {
		return code;
	}
	public String getMessage() {
		return message;
	}
}

PageQueryInfo主要是辅助分页查询,封装了分页查询的一些必备项,比如说查询到的数据一共多少个,每一页有多长,一共多少页

public class PageQueryInfo {
	
	private int count;//查询到的数据总数
	private int limit;//单页行数
	private int totalPage;//总页数
	/**
	 * 查询到的数据
	 */
	private Object data;
	
	
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	
	public int getLimit() {
		return limit;
	}
	public void setLimit(int limit) {
		this.limit = limit;
	}
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	public Object getData() {
		return data;
	}
	public void setData(Object data) {
		this.data = data;
	}
}

Result则是在CodeMsg枚举的基础上再封装

public class Result {
	/**
	 * 业务编码
	 */
	private String code;
	/**
	 * 业务消息
	 */
	private String message;
	/**
	 * 返回的数据
	 */
	private Object data;
	

	public Result(CodeMsg codeMsg) {
		super();
		this.code = codeMsg.getCode();
		this.message = codeMsg.getMessage();
	}
	
	public Result(CodeMsg codeMsg, Object data) {
		super();
		this.code = codeMsg.getCode();
		this.message = codeMsg.getMessage();
		this.data = data;
	}
	
	public Result(CodeMsg codeMsg, String errorMsg) {
		super();
		this.code = codeMsg.getCode();
		this.message = errorMsg;
	}
	
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public Object getData() {
		return data;
	}
	public void setData(Object data) {
		this.data = data;
	}
	/**
	 * 重写toString方法,将对象以JSON字符串的形式输出并传递
	 */
	@Override
	public String toString() {
		return JSONObject.toJSONString(this);
	}
	
	/**
	 * 根据返回的code判断是否登录成功
	 * @return
	 */
	public boolean isSuccess() {
		return "200".equals(this.code);
	}
}

接下来就是导包了,切记我们在做Servlet项目的所有jar包要放在WEB-INF文件夹下的lib子文件夹中而不再是在Java文件的根目录下,因为我们的程序,或者说我们的工作空间是在tomcat的webapps文件夹中

在这里插入图片描述
由于前端是layui框架完成的,所以我这里增加了layui的文件夹,大家可以在layui官网上下载最新版本
在这里插入图片描述

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值