JAVAEE实战1---开发日志

引言:

1、博主目标是成为一名Java开发工程师,所以自学JavaEE,这是博主第一个实战项目,希望将开发过程记录下来,如果有错误,请各位看官评论留言,我一定虚心求教,认真改正。
2、另外此次实战只是我的第一阶段实战,并未用到mybatis和spring框架实现,仅仅用了jsp,servlet,html,css,mvc框架,JDBC技术,比较老套以及繁琐,意在于锻炼基础,以便以后对框架理解更为深入,增加核心竞争力。
3、此篇博客是第一个功能块的实现,前期准备以及项目描述见:项目描述
4、目前代码不适用于重名的情况,对于不重名的情况没问题

基本思路:

前端

1、需要获得购物车信息,将购物车信息打印出来,要考虑购物车为空。
2、需要设计一个form表单,内置表格,将提交的要购买的商品信息以及商品数量传递到后台
3、设计一个判断登陆的模块,已经登陆的直接打印表单,没登陆的先登录或者注册,再显示购物车。
4、支持一键清空购物车(将该用户记录全部删除)

后端

1、servlet:要接收到前端发来的多选框,以及用户姓名,以及选中的商品的数量,发向service,再得到service的处理结果代码,根据不同的代码封装不同的情况再发往前端,在由前端显示结果。
2、service:这是这个后端的核心,所有逻辑算法错误处理都应该在这里!(博主因为经验不足,导致service书写的不好,好多逻辑处理放进了Dao层,我会在代码中进行标识),他是核心服务层。他得到service的三大数据,首先进行错误判断,将可能的三种错误经由error层处理返回错误代码。之后处理正确情况,先让Dao层进入DB查询相应选中商品价格,回到service 进行价格计算,然后让Dao层去把选中的商品置为null,同时删除五个商品栏全空的行,最后命令Dao将记录插入record表,再返回记录Id。
3、Dao:该层就是拿service处理好的精纯数据,来和数据库交互。功能一:进入DB查询相应选中商品价格。功能二:把选中的商品置为null,同时删除五个商品栏全为null的行。功能三:将消费记录插入record表。功能四:查询最新插入的记录Id,并返回。功能五:拿到用户名子查询用户Id。(本系统目前不支持重名)。

代码实现:

1、jsp前端

注:
1、购物车可以为空,必须单独判断
2、用户可能重复选择,必须过滤,并且过滤掉null的商品
3、注意text的表单控件,名字一定要不同,并且要用商品ID去拼名字,因为多选框传到后端的是商品ID,所以这样便于后端去拼出text传过来的名字。

<%@page import="com.webhomework.dao.showGoodsDao"%>
<%@page import="com.webhomework.javabeans.user"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.webhomework.jdbc.JDBCTools"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		String isLogIn = (String)session.getAttribute("name");//模块1,判定是否登录,用session
	%>
	<%
		if(isLogIn != null){
			%>
				<%
					//将所有goods打印出来,做成form表单,可以选择进入购物车
					JDBCTools jdbct = new JDBCTools();
					ArrayList<Map<String,String>>  resultMapOne = new ArrayList<Map<String,String>>();
					ArrayList<Map<String,String>>  resultMapTwo = new ArrayList<Map<String,String>>();
					ArrayList<String> commodityNumber = new ArrayList<String>();
					user u = new user();
					u.setName((String)session.getAttribute("name"));
					showGoodsDao sgd = new showGoodsDao();
					String id = sgd.findIdInDB(u);//利用Dao层功能五获得用户ID
					String sql = "select goods_one,goods_two,goods_three,goods_four,goods_five,is_valid from user u ,goods_car gc where u.id=gc.user_id and u.id="+ id +" and is_valid=false;";
					resultMapOne = jdbct.find(sql);//将查询到的该用户添加到购物车里的东西取出来
					int numOne = resultMapOne.size();
				%>
				<% 
					if(numOne == 0){//判断购物车是否为空
						%>
							<div><b>购物车为空</b></div>
							<div><a href="showGoods.jsp">点击添加商品</a></div>
						<%
					}
				%>
				<%
					if(numOne > 0){
						%>
							<%for(int i = 0 ;i < resultMapOne.size() ;i++){//以下操作为过滤掉重复选择的商品以及为null商品,前者就是利用一个辅助List
							//每进来一个就要与前面比较一下看有无重复,后者就是遍历的时候看一直与否即可
						ArrayList<String> temp = new ArrayList<String>();
						temp.add(resultMapOne.get(i).get("goods_one"));
						temp.add(resultMapOne.get(i).get("goods_two"));
						temp.add(resultMapOne.get(i).get("goods_three"));
						temp.add(resultMapOne.get(i).get("goods_four"));
						temp.add(resultMapOne.get(i).get("goods_five"));
						for(int k = 0 ;k < 5 ;k++ ){
							int j = 0;
							int num = commodityNumber.size();
							if(temp.get(k).equals("null")){
								continue;
							}
							for(;j < num ;j++){
								if(!temp.get(k).equals(commodityNumber.get(j))){
									continue;
								}
								else{
									break;
								}
							}
							if(j == num){
								commodityNumber.add(temp.get(k));
							}
							else{
								continue;
							}
						}
					}
					String sqlAno = "select * from goods where";
					int j = 0;
					for(;j < commodityNumber.size() - 1 ;j++) {
						String ano = " id="+ commodityNumber.get(j) +" or";
						sqlAno += ano;
					}
					String ano = " id="+ commodityNumber.get(j) +";";
					sqlAno += ano;
					resultMapTwo = jdbct.find(sqlAno);//将查到的商品信息存起来一会打印到表格里面
					int num = resultMapTwo.size();
				%>
					<form action="goodsCarServlet" method="post">//注意form里面不仅可以放表单控件,啥都可以放进去包括表格,所以可以采用表格中嵌入表单控件的方法
					<table border="1">
					<tr>
					<th width="20"></th>
					<th>商品名称</th>
					<th>商品类型</th>
					<th>商品数量</th>
					<th>商品价格</th>
					<td width="200">请输入您要的数量</td>
					</tr>
					<%
					for(int i = 0 ;i < num ;i++){
						%>
							<tr>
								<td width="20"><input type="checkbox" name="checkbox" class="check-product" value="<%=resultMapTwo.get(i).get("id") %>" /></td>
								<td width="150" align="left"><%=resultMapTwo.get(i).get("name") %></td>
								<td width="100" align="left"><%=resultMapTwo.get(i).get("type") %></td>
								<td width="100" align="left"><%=resultMapTwo.get(i).get("num") %></td>
								<td width="100" align="left"><%=resultMapTwo.get(i).get("price") %></td>
								<%String Name = "num"+ resultMapTwo.get(i).get("id"); %>//拼名字,保证每个text名字不同,并且用商品ID便于后端接收
								<td width="200">请输入您要的数量 <input type="text" name="<%=Name %>" id="" /></td>
							</tr>
						<% 
					}
					%>
					</table>
					<input type="submit" value="点击结算购物车" />
					</form>
					<form action="deleteGoodsCarServlet" method="post">//一键清空购物车功能
					<input type="submit" value="一键清空购物车" />
					</form>
						<%
					}
				%>
			<%
		}
	%>
	<%
		if(isLogIn == null){//未登录处理
			%>
			<div>
				<b>您好,您未登录,请先登录再观看您的购物车</b>
			</div>
			<div>
				<a href="login.jsp">点击登录</a>
			</div>
			<%
		}
	%>
</body>
</html>

2、servlet

由前端走进后端,表单先被服务器拦截,根据xml的配置以及点击不同的按钮被分别发送到goodsCarServlet中,和deleteGoodsCarServlet中

1、goodsCarServlet

注:
1、服务层才是处理所有逻辑,书写算法,封装结果的地方,所以最好将结果的封装放到service层,博主这里犯错误了,在代码中标号1的位置,记住servlet就是干截数据,发送数据到service,最后在将结果转发的活。

package com.webhomework.control;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

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

import com.webhomework.service.goodsCarService;//service层方法
import com.webhomework.service.showGoodsService;


public class goodsCarServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
   
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");//设置编码结构,防止中文乱码
		Map<Integer,String> resultMap = new HashMap<Integer,String>();
		ArrayList<String> numberList = new ArrayList<String>();
		
		String[] result = request.getParameterValues("checkbox");//获取多选框数据
		String name = (String)request.getSession().getAttribute("name");
		int num = result.length;
		for(int i = 0 ;i < num ;i++) {//这里就看出当时拼接Name的优势了,我直接根据选中的商品Id拼接,第一方便接收拼接名字,第二可以过滤掉无效提交
			String Name = "num";
			Name += result[i];
			numberList.add(request.getParameter(Name).trim());
		}

		goodsCarService gcs = new goodsCarService();//将数据传送到服务层
		int station = gcs.buyGoodsInCarService(result, name, numberList);
		//获得服务层服务结果代码,正整数代表正确,且表示插入记录表中的Id号
		
		switch(station) {//1、封装位置最好在service里面
		//封装服务情况
		case 0 :
			resultMap.put(0, "对不起,购买失败,数据库异常");
			break;
		case -1 :
			resultMap.put(-1, "对不起,购买失败,存在没填写的数");
			break;
		case -2 :
			resultMap.put(-2, "对不起,购买失败,存在越界的数");
			break;
		case -3 :
			resultMap.put(-3, "对不起,购买失败,存在负数");
			break;
		case -4 :
			resultMap.put(-4, "对不起,购买失败,存在没填写的数+越界的数");
			break;
		case -5 :
			resultMap.put(-5, "对不起,购买失败,存在没填写的数+负数");
			break;
		case -6 :
			resultMap.put(-6, "对不起,购买失败,存在越界的数+负数");
			break;
		case -7 :
			resultMap.put(-7, "对不起,购买失败,存在没填写的数+越界的数+负数");
		}
		request.setAttribute("resultMap", resultMap);
		request.setAttribute("key", station);
		request.getRequestDispatcher("goodsCarResult.jsp").forward(request, response);//转发走
	}

}

2、deleteGoodsCarServlet

package com.webhomework.control;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.webhomework.dao.goodsCarDao;


public class deleteGoodsCarServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = (String)request.getSession().getAttribute("name");
		goodsCarDao gcd = new goodsCarDao();
		gcd.deleteAllRecord(name);//这里博主偷懒了,应该发给service处理的才对
		response.sendRedirect("delete.html");
	}

}

3、service

博主这里写错了,其实对数据错误判断,核心算法处理,以及结果封装都应该在这里写的,这里明显少了很多东西!

	package com.webhomework.service;

import java.util.ArrayList;

import com.webhomework.dao.goodsCarDao;
import com.webhomework.errorset.errorGoodsCarSet;

public class goodsCarService {
	/**
	 * Dao层返回来的是插入的购买信息的id
	 * 错误情况,输入的数量超过范围,输入的数量为负数,不输入数量
	 * 
	 */
	public int buyGoodsInCarService(String[] item ,String name ,ArrayList<String> numberList) {
		goodsCarDao gcd = new goodsCarDao();
		errorGoodsCarSet egcs = new errorGoodsCarSet();
		
		boolean hasNullNum = false;//看是否有没填写的数
		boolean transgressive = false;//看是否有越界的数
		boolean hasNegativeNum = false;//看有无负数
		for(int i = 0 ;i < numberList.size() ;i++) {
			int maxNum = gcd.hasMaxNumberInDB(item[i]);
			if(numberList.get(i).equals("")) {//填入为空
				hasNullNum = true;
				continue;
			}
			int num = Integer.parseInt(numberList.get(i));
			if(num > maxNum) {
				transgressive = true;
			}
			if(num < 0) {
				hasNegativeNum = true;
			}
		}
		if(hasNullNum || transgressive || hasNegativeNum) {
			return egcs.erroeGoodsCar(hasNullNum, transgressive, hasNegativeNum);//一旦有任何一种错误就发给错误处理函数,下方会附上
		}
		return gcd.buyGoodsInCarDao(item, name, numberList);//数据精纯正确就发给Dao与数据库进行交互。
	}
}

下面附上错误处理:
这样集中写便于管理!

package com.webhomework.errorset;

public class errorGoodsCarSet {
	/**
	 * 处理特殊情况
	 * -1是存在没填写的数
	 * -2是存在越界的数
	 * -3是存在负数
	 * -4是存在没填写的数+越界的数
	 * -5是存在没填写的数+负数
	 * -6是存在越界的数+负数
	 * -7是存在没填写的数+越界的数+负数
	 */
	public int erroeGoodsCar(boolean hasNullNum , boolean transgressive , boolean hasNegativeNum) {
		if(hasNullNum == true && transgressive == false && hasNegativeNum == false) {
			return -1;
		}
		if(hasNullNum == false && transgressive == true && hasNegativeNum == false) {
			return -2;
		}
		if(hasNullNum == false && transgressive == false && hasNegativeNum == true) {
			return -3;
		}
		if(hasNullNum == true && transgressive == true && hasNegativeNum == false) {
			return -4;
		}
		if(hasNullNum == true && transgressive == false && hasNegativeNum == true) {
			return -5;
		}
		if(hasNullNum == false && transgressive == true && hasNegativeNum == true) {
			return -6;
		}
		return -7;
	}
}


4、dao层

得到service中的精纯数据,来与数据库交互,将得到的值返回去,千万不要进行操作,他就是交互,而不是进行逻辑操作。

package com.webhomework.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.webhomework.javabeans.user;
import com.webhomework.jdbc.JDBCTools;

public class goodsCarDao {
	/**
	 * 处理购买业务,这里只处理正确情况,错误情况见service层,处理逻辑在error里面
	 * 购买成功,返回1,代表购买信息已经插入表中
	  *  购买失败返回0,代表插入出错
	  *  查询单价,计算总金额,写入记录,把已经买的东西从购物车里移除,全空的车移除,返回记录的id;
	  *  错误情况,输入的数量超过范围,输入的数量为负数,不输入数量
	 */
	/**
	 * 处理特殊情况
	 * -1是存在没填写的数
	 * -2是存在越界的数
	 * -3是存在负数
	 * -4是存在没填写的数+越界的数
	 * -5是存在没填写的数+负数
	 * -6是存在越界的数+负数
	 * -7是存在没填写的数+越界的数+负数
	 * 大于等于1代表购买正常,返回值为record表中记录位置
	 */
	//dao只查询插入返回
	public int buyGoodsInCarDao(String[] item ,String name ,ArrayList<String> numberList) {
		JDBCTools jdbct = new JDBCTools();
		ArrayList<Map<String,String>> resultMap = new ArrayList<Map<String,String>>();
		ArrayList<Map<String,String>> anoResultMap = new ArrayList<Map<String,String>>();
		
		user u = new user();
		u.setName(name);
		String ID = findIdInDB(u);
		
		String sqlOne = "select price from goods where";//功能1查价格
		for(int i = 0 ;i < item.length - 1 ;i++) {
			String temp = " id = "+item[i]+" or";
			sqlOne += temp;
		}
		sqlOne = sqlOne + " id = " + item[item.length - 1] +";";
		System.out.println(sqlOne);
		resultMap = jdbct.find(sqlOne);
		//下面回service,下面是计算价格,应该回到service去
		double money = 0;
		System.out.println(resultMap.size());
		for(int i = 0 ;i < resultMap.size() ;i++) {
			double price = Double.parseDouble(resultMap.get(i).get("price"));
			System.out.println(price);
			double number = Double.parseDouble(numberList.get(i));
			System.out.println(number);
			money += price*number;
			System.out.println(money);
		}
		
		//功能2把已经买的物品去掉
		String goodsNum[] = {"goods_one","goods_two","goods_three","goods_four","goods_five"};
		for(int i = 0 ;i < item.length ;i++) {
			for(int j = 0 ;j < 5 ;j++) {
				String sqlTwo = "update goods_car set "+ goodsNum[j] +" = 'null' where user_id = "+ID+" and "+ goodsNum[j] +" = "+ item[i] +";";
				jdbct.update(sqlTwo);
			}
		}
		//功能3把全是空的行删除
		String sqlThree = "delete from goods_car where goods_one = 'null'and goods_two='null' and goods_three='null'and goods_four='null'and goods_five='null';";
		jdbct.update(sqlThree);
		
		//插入销售记录,返回记录ID
		String sqlFour = "insert into record (name,money) values('"+ name +"','"+ money +"')";
		jdbct.update(sqlFour);
		
		String sqlFive = "select * from record";
		anoResultMap = jdbct.find(sqlFive);
		
		int mapSize = anoResultMap.size();
		return Integer.parseInt(anoResultMap.get(mapSize - 1).get("id"));
	}
	
	public String findIdInDB(user u) {//功能5根据用户名字查找用户ID
		JDBCTools jdbct = new JDBCTools();
		List<Map<String,String>> resultList = new ArrayList<Map<String,String>>();
		Map<String,String> resultMap = new HashMap<String,String>();
		//未处理重名情况,处理的话把session中name换为一个List即可
		String sql = "select * from user where name= '"+ u.getName() +"';";
		resultList = jdbct.find(sql);
		resultMap = resultList.get(0);
		return resultMap.get("id");
	}
	
	public int hasMaxNumberInDB(String goodsID) {//判断是输入的数字是否超过库存,错误判断
		JDBCTools jdbct = new JDBCTools();
		String sql = "select num from goods where id = "+ goodsID +";";
		ArrayList<Map<String,String>> resultMap = new ArrayList<Map<String,String>>();
		resultMap = jdbct.find(sql);
		return Integer.parseInt(resultMap.get(0).get("num"));
	}
	
	public String selectMoneyInRecord(int key) {//根据record的id号查询花了多少钱
		JDBCTools jdbct = new JDBCTools();
		ArrayList<Map<String ,String>> resultList = new ArrayList<Map<String ,String>>();
		String sql = "select * from record where id = "+ key +";";
		resultList = jdbct.find(sql);
		return resultList.get(0).get("money");
	}
	
	

	public void deleteAllRecord(String name) {//用于一键清空某用户购物车
		JDBCTools jdbct = new JDBCTools();
		user u = new user();
		u.setName(name);
		String ID = findIdInDB(u);
		String sql = "delete from goods_car where user_id = "+ ID +";";
		jdbct.update(sql);
	}
}

5、返回

从dao层返回数值到service 再回到servlet,在最后由servlet发给显示结果页面。

<%@page import="com.webhomework.dao.goodsCarDao"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.Map"%>
<%@page import="com.webhomework.jdbc.JDBCTools"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		JDBCTools jdbct = new JDBCTools();
		Map<Integer,String> resultMap = (Map<Integer,String>)request.getAttribute("resultMap");
		ArrayList<Map<String ,String>> resultList = new ArrayList<Map<String ,String>>();
		int key = (Integer)request.getAttribute("key");
		goodsCarDao gcs = new goodsCarDao();
		if(resultMap.size() == 0){//看传过来的是不是代表了发生错误的代码
			%>
			<b>您一共消费</b>
			<%=gcs.selectMoneyInRecord(key) %>//根据record表里的id号查询花了多少钱
			<%
		}
		else{
			%>
			<%=resultMap.get(key) %>
			<%
		} 
	%>
	
	<div>
		<a href="body.jsp">点击回到主页面</a>
	</div>
	<div>
		<a href="showGoods.jsp">点击添加商品</a>
	</div>
	<div>
		<a href="goodsCar.jsp">点击继续结算商品</a>
	</div>
</body>
</html>

Sum Up:

1、一定注意要将最复杂的逻辑处理放在service层,别的层一定要功能单一!
2、form表单里并不是只能放控件,其实啥都能放,一定要灵活。
3、前端在准备form:text名字的时候,一定要根据要求,尽可能方便后端接收,这样就可以减少错误处理。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JLU_LYM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值