基于servlet和jsp的shop项目
一、项目开发流程
1.数据库分析
2.环境搭建
导包,配置文件,导入静态页面,导入工具类,创建项目包结构
二、注册
1.编写user实体类
public class User {
private String uid;
private String username;
private String password;
private String name;
private String email;
private String telephone;
private Date birthday;
private String sex;
private int state;//0--未激活 1--激活
private String code;//激活码
set get 方法省略
}
2.修改静态页面register.jsp
<form class="form-horizontal" action="${pageContext.request.contextPath}/registerServlet" method="post" style="margin-top: 5px;">
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="username" name="username"
placeholder="请输入用户名">
3.编写servlet和service
将表单提交到registerServlet ,在web包中创建RegisterServlet,并将路径改为registerServlet
在register()方法中 (此时用了状态分发)
首先用request将编码转化为utf-8;
创建一个User对象,用来存储从前台register.jsp 中获取的表单数据
因为从表单中获取的数据是字符串类型,所以需要用注册转化器将String类型转化为Date类型
将从表单中获取的数据通过BeanUtils.populate()方法封装到User对象中
此时再设置User对象的uid和激活码code
再调用service层中的RegisterService类中的regist()方法,将user插入到数据库中
注册成功的话就就需要用邮件激活用户的激活码
通过调用MailUtils中的sendMail()方法发送邮件,通过点击链接跳转到RegisterServlet的activeCode方法来更改激活码的状态
并跳转到注册成功的页面,在注册成功的页面是邮箱,接受发过来的邮件激活激活码,并重定向到login.jsp页面
否则就返回注册失败页面。
RegisterServlet.java
public class registerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
RegisterService rs=new RegisterService();
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String state=request.getParameter("state");
if (state.equals("register")) {
register(request, response);
}else if (state.equals("activeCode")) {
activeCode(request, response);
}
}
protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
User user =new User ();
try {
//1.手动将String转化Date类型(BeanUtils包下的注册转化器,将String类型转化为Date类型)
ConvertUtils.register(new Converter(){
public Date convert(Class clazz,Object value){
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
Date desc=null;
try {
desc= sf.parse((String)value);
} catch (ParseException e) {
e.printStackTrace();
}
return desc;
}
}, Date.class);
//2. 组成USer实体对象
BeanUtils.populate(user, request.getParameterMap());
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
String code = StringUtils.getUUID();
user.setUid(StringUtils.getUUID());
user.setCode(code);
RegisterService rs=new RegisterService();
boolean isSucess = rs.regist(user);
if (isSucess==true ) {
//发送邮件,激活用户
String emailMsg="恭喜你,注册成功,点击下面的连接进行账户激活<br>"
+"<a href='http://localhost:8080/shop02/active?activeCode="+code+"'>http://localhost:8080/shop02/active?activeCode="+code+"</a>";
try {
MailUtils.sendMail(user.getEmail(), emailMsg);
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
//跳转成功页面
response.sendRedirect(request.getContextPath()+"/registerSuccess.jsp");
}else {
request.setAttribute("msg", "注册失败,重新注册!");
request.getRequestDispatcher("/register.jsp").forward(request, response);
}
}
protected void activeCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String code = request.getParameter("activeCode");
if (rs.activeCode(code)) {
// 跳转到登录页面
response.sendRedirect(request.getContextPath() + "/login.jsp");
} else {
// 激活失败
response.sendRedirect(request.getContextPath() + "/error.jsp");
}
}
RegisterService.java
BaseDao dao =new BaseDao();
//注册方法
public boolean regist(User user ){
String sql="insert into user values(?,?,?,?,?,?,?,?,?,?)";
Object[] params={user.getUid(),user.getUsername(),user.getPassword(),
user.getName(),user.getEmail(),user.getTelephone(),user.getBirthday(),
user.getSex(),user.getState(),user.getCode()};
int i = dao.updata(sql, params);
return i>0?true:false;
}
//激活激活码
public boolean activeCode(String code){
String sql="update user set state =1 where code=?";
Object[] params={code};
int i=dao.updata(sql,params );
return i>0?true:false ;
}
4.ajax校验
而此时在前端还需要进行ajax校验,首先要引入校验插件
<script src="js/jquery.validate.min.js" type="text/javascript"></script>
首先要自定义一个用户名验证是够重复的校验方法,代码如下
<script type="text/javascript">
//自定义校验规则
$.validator.addMethod(
"checkUsername",//自定义校验规则的名称
function(value,element,params){//自定义校验规则的实现
//value)表单元素值
//element)校验的元素对象
//params)校验规则输入的参数
var flag = true;
//发送一个Ajax,到服务器进行验证用户存在
$.ajax({
"async":false,//同步操作
"url":"${pageContext.request.contextPath}/user/CheckUser",
"type":"POST",
"data":{"username":value},
"dataType":"json",
"success":function(data){
flag = data.isExist;//true--存在 false--不存在
}
});
//需要返回值 false----该校验器校验失败 true---校验通过
return !flag;
}
)
$(function(){
$("#registForm").validate({
rules:{
"username":{
"required":true,
"checkUsername":true
},
"password":{
"required":true,
"rangelength":[6,12]
},
"confirmpwd":{
"required":true,
"rangelength":[6,12],
"equalTo":"#password"
},
"email":{
"required":true,
"email":true
},
"telephone":{
"required":true
},
"name":{
"required":true
},
"birthday":{
"required":true,
"date":true
},
"sex":{
"required":true
}
},
messages:{
"username":{
"required":"用户名不能为空",
"checkUsername":"该用户已存在"
},
"password":{
"required":"密码不能为空",
"rangelength":"密码长度在6-12位"
},
"confirmpwd":{
"required":"确认密码不能为空",
"rangelength":"确认密码长度在6-12位",
"equalTo":"两次密码不一致"
},
"email":{
"required":"邮箱不能为空",
"email":"邮箱格式不正确"
},
"telephone":{
"required":"电话不能为空"
},
"name":{
"required":"真实姓名不能为空"
},
"birthday":{
"required":"生日不能为空",
"date":"日期格式不正确"
},
"sex":{
"required":"性别必须选择"
}
},
errorPlacement: function (error, element) { //指定错误信息位置
if (element.is(':radio') || element.is(':checkbox')) { //如果是radio或checkbox
error.appendTo(element.parent().parent()); //将错误信息添加当前元素的父结点后面
} else {
error.insertAfter(element);
}
}
});
})
</script>
三、登录
1.修改login.jsp页面
将login.jsp页面的登录表单提交到login/LoginServlet 并且验证码的地方生成动态验证码
<font>会员登录</font>USER LOGIN
<div> </div>
<!-- 要提交给处理注册的servlet -->
<form action="${root}/login/LoginServlet" method="post" class="form-horizontal">
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="inputPassword3"
placeholder="请输入验证码" name="checkcode">
</div>
<div class="col-sm-3">
<!-- 修改验证码。 动态的验证码 。-->
<img src="${root}/login/checkcode" onclick="changeImg(this)"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label> </label> <label> <input type="checkbox" onclick="r(this)" value="off" name="remember"> 自动登录 <span style="color: red">${msg }${msg2 }</span>
</label>
</div>
</div>
</div>
<script>
//obj就代表了你传入的图片对象。
function changeImg(obj){
//alert(obj);
//注意 当前参数改变的时候 才会重新去请求你的Servlet...
obj.src="${root}/login/checkcode?a="+new Date().getTime();
}
function r(obj){
if(obj.checked==true)
obj.value="on";
else
obj.value="off";
}
</script>
2.编写LoginServlet
获取表单中的数据通过BeanUtils封装到User对象中
检查user对象的username和password是否和数据库中的数据一致,并且要判断激活码是否为1 ,为1 的时候才能登录,这里还要实现一个记住密码的功能,用的是cookie技术,将用户名和密码放到cookie中 ,同时还创建一个过滤器,如果发现cookie中有username和password两个cookie,并且和数据库里的数据一致,那么将自动登录,在配置web中url-pattern中要过滤login.jsp(所谓的登录,就是user对象放入到session域中,自动登录就是从cookie中获取user,放入到session域中)
LoginServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String[]> parameterMap = request.getParameterMap();
User user=new User();
try {
//将表单中的数据封装到user对象中去
BeanUtils.populate(user, parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
String username = user.getUsername();
String password = user.getPassword();
HttpSession session = request.getSession();
LoginService service=new LoginService();
User checkUser = service.getUser(username, password);
String checkcode1= request.getParameter("checkcode");
String checkcode2 = (String) session.getAttribute("checkcode");
if (!checkcode1.equalsIgnoreCase(checkcode2)) {
request.setAttribute("msg", "验证码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return ;
}else{
if (checkUser==null) {
request.setAttribute("msg", "用户名或者密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return ;
}else if(checkUser.getState()==1&&checkUser!=null){
String remember = request.getParameter("remember");
if ( remember!=null&&remember.equals("on")) {
//需要记住名字。密码
Cookie username_cookie=new Cookie ("username",username);
Cookie passWord_cookie=new Cookie("password",password);
username_cookie.setPath("/");
username_cookie.setMaxAge(60*60*24);
response.addCookie(username_cookie);
passWord_cookie.setPath("/");
passWord_cookie.setMaxAge(60*60*24);
response.addCookie(passWord_cookie);
}
session.setAttribute("user", checkUser);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else if (checkUser!=null&&checkUser.getState()==0) {
request.setAttribute("msg", "用户没有激活");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
loginFilter.java
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//写一个过滤器 来拦截index.jsp 和 login.jsp .
//先判断当前请求参数中是否携带有cookie...
//cookie的形式呢 就是email=a
//根据你发送过来的cookie中的用户名,查到当前用户中所有的数据,让后将查询到的结果放入到sessio中
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
String cookie_username = null;
String cookie_password = null;
// 获取携带用户名和密码cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// 获得想要的cookie
if ("username".equals(cookie.getName())) {
cookie_username = cookie.getValue();
}
if ("password".equals(cookie.getName())) {
cookie_password = cookie.getValue();
}
}
}
if (cookie_username != null && cookie_password != null) {
// 去数据库校验该用户名和密码是否正确
LoginService service = new LoginService();
user = service.getUserByCookie(cookie_username, cookie_password);
// 完成自动登录
request.getSession().setAttribute("user", user);
}
}
chain.doFilter(request, response);
}
LoginService.java
public class LoginService {
private BaseDao <User> dao=new BaseDao<User>();
public User getUser(String username,String password){
String sql="select * from user where username=? and password=?";
Object[] params={username,password};
User user =(User) dao.getByOne(sql, params, new User());
return user;
}
public User getUserByCookie(String username ,String password){
String sql="select * from user where username=? and password=?";
Object[] params={username,password};
User user =(User) dao.getByOne(sql, params, new User());
return user;
}
public boolean checkUser(String username){
String sql="select * from user where username=?";
Object[] params={username};
User byOne = (User) dao.getByOne(sql, params, new User());
return byOne==null?false:true;
}
}
3.前端页面登录状态
此时还要在前端页面将用户名显示出来,来提示当前是登录状态
用c标签需要引入c标签的包
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${empty user }">
<li><a href="${root}/login.jsp">登录</a></li>
<li><a href="${root}/register.jsp">注册</a></li>
</c:if>
<c:if test="${not empty user }">
<li><a href="user.jsp">${user.username}</a></li>
<li><a href="${root}/LonginOutServlet">注销</a></li>
</c:if>
而注销的功能跳转到了LonginOutServlet中
首先移除session域中的user对象,如果是自动登录,那就需要将cookie移除掉
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.removeAttribute("user");
session.invalidate();
Cookie username_cookie = new Cookie("username", "");
username_cookie.setMaxAge(0);
System.out.println("--------------------");
// 创建存储密码的cookie
Cookie passWord_cookie = new Cookie("password", "");
passWord_cookie.setMaxAge(0);
Cookie pid = new Cookie("pids", "");
pid.setMaxAge(0);
response.addCookie(username_cookie);
response.addCookie(passWord_cookie);
response.addCookie(pid);
System.out.println(username_cookie.getName()+"---======-"+username_cookie.getValue());
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
四、index页面
1.index.jsp页面的最新最热商品
需要一个过滤器,只要访问index.jsp 页面,就将查询到的最新最热商品放到request域中,并将数据在前台页面中展现出来 url-patten 改写成index.jsp
public class IndexFilter implements Filter {
IndexService is=new IndexService();
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
List<Product> hotShop = is.getHot();
List<Product> newShop = is.getNew();
request.setAttribute("hotShop", hotShop);
request.setAttribute("newShop", newShop);
//request.getRequestDispatcher("/index.jsp").forward(request, response);
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
index页面
<!-- 热门商品 -->
<div class="container-fluid">
<div class="col-md-12">
<h2>热门商品 <img src="${root }/img/title2.jpg"/></h2>
</div>
<div class="col-md-2" style="border:1px solid #E7E7E7;border-right:0;padding:0;">
<img src="${root }/products/hao/big01.jpg" width="205" height="404" style="display: inline-block;"/>
</div>
<div class="col-md-10">
<div class="col-md-6" style="text-align:center;height:200px;padding:0px;">
<a href="product_info.htm">
<img src="${root }/products/hao/middle01.jpg" width="516px" height="200px" style="display: inline-block;">
</a>
</div>
<c:forEach items="${hotShop }" var="hotShop">
<div class="col-md-2" style="text-align:center;height:200px;padding:10px 0px;">
<a href="product_info.htm">
<img src="${root }/${hotShop.pimage}" width="130" height="130" style="display: inline-block;">
</a>
<p><a href="product_info.html" style='color:#666'>${hotShop.pname}</a></p>
<p><font color="#E4393C" style="font-size:16px">¥${hotShop.shop_price}</font></p>
</div>
</c:forEach>
/div>
</div>
最新商品代码省略,与最热商品一样
2.分类列表
通过ajax技术将商品分类展示到前台页面上,url跳转到IndexProductServlet?state=categoryList中去获取总的商品分类。
<script type="text/javascript">
$(function(){
var content="";
//发送AJAX请求 到后台服务器获取数据
$.post(
"${root}/index/IndexProductServlet?state=categoryList",
function(data){
//解析date 将数据绑定到页面中
for (var i = 0; i < data.length; i++) {
content+="<li><a href='${root}/index/IndexProductServlet?state=productList&page=1&cid="+data[i].cid+"'>"+data[i].cname+"</a></li>";
}
//动态绑定到页面中
$("#categoryUl").html(content);
},
"json"
);
});
</script>
protected void categoryList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Category> list = as.queryCategory();
Gson gson=new Gson();
String json = gson.toJson(list);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(json);
}
3.商品列表分页
每一个商品列表是a标签,要跳转的页面是/index/IndexProductServlet?state=productList 同时要传入page参数和商品分类cid,于此同时要创建一个pageBean的类,将分页页面封装到pageBean类中
public class PageBean<T> {
private int pageNumber;//当前页
private int pageSize;//每页显示的条数
private int totalDataNUmber;//总记录条数
/*需要计算的数据 */
private int totalPage;//总页数
/*需要查询数据的索引*/
private int startIndex;//开始的数据索引 limit startIndex , pageSize;
//分页显示的页数 页面显示1,2,3,4,5 页 则开始start=1 end=5
/**前台开始数字*/
private int start;
/**前台结束数字*/
private int end;
//需要在当前页展示的数据
private List<T> data;
private String cid;//cid是商品分类的cid
//初始化
public PageBean(int pageNumber, int pageSize, int totalDataNUmber) {
super();
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.totalDataNUmber = totalDataNUmber;
//计算总的页数
if (totalDataNUmber%pageSize==0) {
totalPage=totalDataNUmber/pageSize;
}else {
totalPage=totalDataNUmber/pageSize+1;
}
//计算开始的索引 (已经显示了的数据)
startIndex=(pageNumber-1)*pageSize;
//(页面上要显示的数字区域,唯一有点小绕的地方。)
//计算页面上要显示的开始跟结束下标。以默认每页显示5页为例。
start=1;//默认从第一页开始
end=5;//默认到第五页结束
if(totalPage<=5){
//如果总页数不足5页那么刚好 结束数字
end=totalPage;
}else{
//否则就是页面上要显示的页数大于5页。要根据当前页来判断start跟end
start=pageNumber-2;
end=pageNumber+2;
if(start<=0){
//如果开始位置<=0,则表示是第一页或者第二页还正常显示1,2,3,4,5 不适用上面的加减规则
start=1;
end=5;
}
if(end>=totalPage){
//如果结束位置+2后大于总页数,则表示当前页是倒数第二页或者倒数第一页,不适用上面的加减规则
start=totalPage-4;
end=totalPage;
}
}
}
get set 方法省略
}
在productList方法中要获取传入的两个参数,在数据库中拿到每个分类下的总商品数量,然后new一个pageBean对象,将当前的页数和每页要显示的商品数,和每个分类下总的商品数量传入进去。通过商品分类的cid和pageBean中的当前页和当前页显示的商品数量查到每页的商品列表,将商品列表和cid封装到pageBean中
最后将pageBean对象放到session中,并请求转发到商品列表页面,
在页面中展示数据
protected void productList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cid = request.getParameter("cid");
String i = request.getParameter("page");
//List<Product> productList1 = ps.getProByCid(cid);
BaseDao dao=new BaseDao();
//拿到每个分类的product数据量
int countByCid = dao.getCountByCid(cid);
//将当前页 每页显示的数据 总的数据数传入到pageBean构造器中
PageBean pageBean =new PageBean(Integer.parseInt(i),6,countByCid);
//拿到分页查询的结果
List<Product> productList = ps.getProductListByLimit(cid,pageBean );
//将数据放到session中
pageBean.setData(productList);
pageBean.setCid(cid);
request.getSession().setAttribute("pageBean", pageBean);
request.getRequestDispatcher("/product_list.jsp").forward(request, response);
}
public List<Product> getProductListByLimit(String cid,PageBean pageBean) {
String sql="select * from product where cid=? limit ?,?";
Object [] params={cid ,pageBean.getStartIndex(),pageBean.getPageSize()};
List<Product> list = (List<Product>) dao.getList(sql, params, new Product());
return list;
}
<c:forEach items="${pageBean.data }" var="product">
<div class="col-md-2" style="height: 230px">
<a href="${root }/index/IndexProductServlet?state=productInfo&pid=${product.pid}&cid=${product.cid}&page=${pageBean.pageNumber}"> <img src="${root }/${product.pimage}"
width="170" height="170" style="display: inline-block;">
</a>
<p>
<a href="${root }/index/IndexProductServlet?state=productInfo&pid=${product.pid}&cid=${product.cid}&page=${pageBean.pageNumber}" style='color: green'>${product.pname }</a>
</p>
<p>
<font color="#FF0000">商城价:¥${product.shop_price }</font>
</p>
</div>
</c:forEach>
</div>
<!--分页 -->
<div style="width: 380px; margin: 0 auto; margin-top: 50px;">
<ul class="pagination" style="text-align: center; margin-top: 10px;">
<li>
<a href="${root }/index/IndexProductServlet?state=page&page=1&cid=${pageBean.cid}" aria-label="Previous" >
<span aria-hidden="true">首页</span>
</a>
</li>
<c:if test="${pageBean.pageNumber==1}">
<li class="disabled">
<a href="javascript:void(0);" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
</c:if>
<c:if test="${pageBean.pageNumber!=1}">
<li>
<a href="${root }/index/IndexProductServlet?state=page&page=${pageBean.pageNumber-1}&cid=${pageBean.cid}" aria-label="Previous" >
<span aria-hidden="true">«</span>
</a>
</li>
</c:if>
<c:forEach begin="${pageBean.start}" end="${pageBean.end}" step="1" var="i">
<li <c:if test="${i == pageBean.pageNumber }"> class="active"</c:if>>
<a href="${root}/index/IndexProductServlet?state=page&page=${i}&cid=${pageBean.cid}">${i}</a>
</li>
</c:forEach>
<c:if test="${pageBean.pageNumber==pageBean.totalPage}">
<li class="disabled">
<a href="javascript:void(0);" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
<c:if test="${pageBean.pageNumber!=pageBean.totalPage}">
<li>
<a href="${root }/index/IndexProductServlet?state=page&page=${pageBean.pageNumber+1}&cid=${pageBean.cid}" aria-label="Next" >
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
<li>
<a href="${root}/index/IndexProductServlestate=page&page=${pageBean.totalPage}&cid=${pageBean.cid}" aria-label="Next">
<span aria-hidden="true">尾页</span>
</a>
</li>
</ul>
</div>
<!-- 分页结束 -->
在前端页面的分页中,要进行判断,若是第一页或者最后一页,不能点击,点击上一页或者下一页的时候,传入的page要减一或者加一,首页和尾页,传入的page参数要等于1或者总的页数
4.商品详情+浏览记录
每个商品跳转到
${root }/index/IndexProductServlet?state=productInfo&pid=${product.pid}&cid=${product.cid}&page=${pageBean.pageNumber}
传入商品id ,商品分类cid 和当前商品的页码,此时还需要做一个返回商品列表,将浏览的商品展示到浏览记录中
在这里用的是cookie技术,将浏览的商品的pid存放到cookie中。先获取cookie,如果cookie中有名为pids的cookie,那么将现在浏览的商品的pid加进去,用“,”隔开,这里先判断是否有这个商品,如果有移除,重新添加,将pids转化成字符串数组,再将字符串数组转化为ArrayList,再转化为LinkedList这样方便操作数据,将现在浏览的商品id添加到第一个。
private void productInfo(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String pid = request.getParameter("pid");
Product product = ps.getPro(pid);
String cid = request.getParameter("cid");
String page = request.getParameter("page");
String pids=pid;
Cookie [] cookies =request.getCookies();
if (cookies!=null) {
for (Cookie cookie : cookies) {
if ("pids".equals(cookie.getName())) {
pids=cookie.getValue();
//获取cookie的值后转化为字符串
String[] str = pids.split(",");
//将数据转化为LinkedList 操作更简便
List<String> asList = Arrays.asList(str);
LinkedList <String> list= new LinkedList<String >(asList);
if (list.contains(pid)) {
list.remove(pid);
}
//无论充不重复都要添加在起始位置
list.addFirst(pid);
StringBuffer sb=new StringBuffer();
for (int i = 0; i < list.size()&&i<7; i++) {
sb.append(list.get(i));
sb.append(",");
}
sb.substring(0,sb.length()-1);
pids = sb.toString();
}
}
}
Cookie cookie=new Cookie("pids",pids);
response.addCookie(cookie);
request.setAttribute("cid", cid);
request.setAttribute("page", page);
request.setAttribute("product1", product);
request.getRequestDispatcher("/product_info.jsp").forward(request, response);
}
在前台展示数据
在点击返回商品列表时要继续请求page这个方法,传入page和cid参数
<div><a href="${root }/index/IndexProductServlet?state=page&page=${page}&cid=${cid}">返回列表</a></div>
protected void page(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//从前台获取当前页的页码
String pageNumber = request.getParameter("page");
String cid = request.getParameter("cid");
BaseDao dao = new BaseDao();
int countByCid = dao.getCountByCid(cid);
//将当前页的页码 和 每页显示的数据量 和 总的数据量 传入到PageBean中
PageBean pageBean = new PageBean(Integer.parseInt(pageNumber),6,countByCid);
//当前页要显示的数据
List<Product> productListByLimit = ps.getProductListByLimit(cid,pageBean);
pageBean.setCid(cid);
//将当前页显示的数据放到PageBean中
pageBean.setData(productListByLimit);
request.getSession().setAttribute("pageBean", pageBean);
Cookie[] cookies = request.getCookies();
List<Product> historyList=new ArrayList<Product>();
if (cookies!=null) {
for (Cookie c : cookies) {
if (c.getName().equals("pids")) {
String pids = c.getValue();
System.out.println(pids);
String[] pidsArr = pids.split(",");
for (String pid : pidsArr) {
Product pro = ps.getPro(pid);
historyList.add(pro);
}
}
}
}
request.getSession().setAttribute("historyList", historyList);
response.sendRedirect(request.getContextPath()+"/product_list.jsp");
/*
* 加入 得到的page==1
* 当前页码 pageNumber=1
* 获取总的数据量
* 将 当前页码 和 每页显示的数据量 总的数据量 传入pageBean中
* 在pageBean的构造器中 会执行代码
* startIndex=(pageNumber-1)*pageSize; 就是要分页时候的下标 limit 0,6;
* 传入的
* 再调用service类中的分页方法 获取分页的商品数据,并将数据放到PageBean中 再将pageBean 放到session域中
* 最后返回product_list.jsp页面
*
*
* 若当前页面page=2时
*
*/
}
}
5购物车
A.添加购物车
这里的购物车功能用的是session技术,会存在一些bug,在商品详情页面的添加购物车中,发送请求到
<script type="text/javascript">
function addCart() {
var buyNum=$("#quantity").val();
window.location="${root}/buy/BuyServlet?state=addCart&pid=${product1.pid}&buyNum="+buyNum;
}
</script>
传入参数pid和要购买的商品数量
在此之前要先创建cart类和cartItem类,将页面中的数据封装到两个类里面
public class CartItem {
private Product product;//购物项中的商品
private int buyNum;//购买商品的数量
private double subTotal;//商品的小计
.......
}
public class Cart {
//购物车中的所有的购物项集合
private Map<String ,CartItem> cartItems=new HashMap<String ,CartItem>();
//总计
private double total;
......
}
在addCart方法中
protected void addCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String num = request.getParameter("buyNum");
int buyNum=1;
String pid = request.getParameter("pid");
HttpSession session = request.getSession();
Product pro = ps.getPro(pid);
//判断购买的数量如果<1,那就是非法的,转入错误页面
if (num!=null) {
buyNum = Integer.parseInt(num);
if (buyNum<=0) {
request.setAttribute("error", "您输入数值"+buyNum+"非法,请核对后再提交");
//输入数据非法
request.getRequestDispatcher("/error.jsp").forward(request, response);
return;
}
}
//合计
double subTotal=pro.getShop_price()*buyNum;
//购物车应该从session中获取 如果有则合并到一起,如果没有则创建购物车对象
Cart cart = (Cart) session.getAttribute("cart");
double newSubTotal = subTotal;
if (cart==null) {
//session中没有cart对象
cart=new Cart();
}
//获取都购物车后判断该商品是否存在
Map<String, CartItem> cartItems = cart.getCartItems();
if (cartItems.containsKey(pid)) {
//存在 ,合并该pid对应的商品的buyNum 和subTotal
int oldBuyNum=cartItems.get(pid).getBuyNum();
buyNum+=oldBuyNum;
//合并小计
newSubTotal=buyNum*pro.getShop_price();
}
//如果不包含该商品,就将该商品封装到cartItem中,并添加到cart里面
CartItem cartItem=new CartItem(pro,buyNum,newSubTotal);
cart.getCartItems().put(pid, cartItem) ;
cart.setTotal(cart.getTotal()+subTotal);
session.setAttribute("cart", cart);
response.sendRedirect(request.getContextPath()+"/cart.jsp");
}
再在前端页面获取数据,并展示数据
<c:forEach items="${cart.cartItems }" var="cartItem">
<tr class="active">
<td width="60" width="40%">
<input type="hidden" name="id" value="22">
<img src="${root }/${cartItem.value.product.pimage}" width="70" height="60">
</td>
<td width="30%">
<a target="_blank">${cartItem.value.product.pname}</a>
</td>
<td width="20%">
¥${cartItem.value.product.shop_price}
</td>
<td width="10%">
<input type="text" name="quantity" value="${cartItem.value.buyNum }" maxlength="4" size="10">
</td>
<td width="15%">
<span class="subtotal">¥${cartItem.value.subTotal }</span>
</td>
<td>
<a href="javascript:;" class="delete" onclick="delFromCart('${cartItem.value.product.pid}')">删除</a>
</td>
</tr>
</c:forEach>
B.删除购物项
删除之前到用户确认删除,需要用js来实现
<script type="text/javascript">
function delFromCart(pid){
if(confirm("您确定要删除该商品吗?")){
//跳转到删除的后台
window.location="${root}/buy/BuyServlet?state=delFromCart&pid="+pid;
}
}
function cleanCart(){
if(confirm("您确定要清空购物车吗?")){
//跳转到删除的后台
window.location="${root}/buy/BuyServlet?state=cleanCart";
}
}
</script>
跳转到删除的方法
protected void delFromCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pid = request.getParameter("pid"); //得到要删除的商品pid
HttpSession session = request.getSession();
Cart cart = (Cart) session.getAttribute("cart");//获取cart
Map<String, CartItem> cartItems = cart.getCartItems(); //得到购物车中的购物项集合
Set<String> keySet = cartItems.keySet();
double subTotal=0;
for (String key : keySet) {//遍历每个购物项
CartItem cartItem = cartItems.get(key);
if (cartItem.getProduct().getPid().equals(pid)) {//如果购物项中有这个商品,删除,并拿 //到这里商品项的小计,在之后减去
cartItems.remove(pid);
subTotal=cartItem.getSubTotal();
}
}
cart.setCartItems(cartItems);
cart.setTotal(cart.getTotal()-subTotal);//总价中减去删除的商品项的小计
session.setAttribute("cart", cart);
request.getRequestDispatcher("/cart.jsp").forward(request, response);
}
C.清空购物车
protected void cleanCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Cart cart = (Cart) session.getAttribute("cart");
if (cart!=null) {
session.removeAttribute("cart");
}
request.getRequestDispatcher("/cart.jsp").forward(request, response);
}
将cart从session中移除掉
6订单
转入order方法
protected void order(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
LoginService ls=new LoginService();
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
Cart cart = (Cart) session.getAttribute("cart");
if (user==null) {//首先要判断用户是否登录,没有登录跳转到登录页面
response.sendRedirect(request.getContextPath()+"/login.jsp");
return ;
}
//先创建一个order类,设置属性
Order order = new Order();
order.setOid(StringUtils.getUUID());
order.setTotal(cart.getTotal());
order.setOrdertime(new Date());
order.setUser(user);
//获取cartItem,将每个购物项的数据转化为orderItem
Map<String, CartItem> cartItems = cart.getCartItems();
Set<String> keySet = cartItems.keySet();
for (String key : keySet) {
OrderItem orderItem=new OrderItem();
//得到每一个购物项
CartItem cartItem = cartItems.get(key);
Product pro=cartItem.getProduct();
orderItem.setItemid(StringUtils.getUUID());
orderItem.setCount(cartItem.getBuyNum());
orderItem.setOrder(order);
orderItem.setProduct(pro);
orderItem.setSubtotal(cartItem.getSubTotal());
order.getOrderItems().add(orderItem);
}
//将封装好数据的order和orderItem插入数据库
ProductService ps=new ProductService();
ps.submitOrders(order);
session.setAttribute("order", order);
response.sendRedirect(request.getContextPath()+"/order_info.jsp");
}
public void submitOrders(Order order) {
try {
//1.开启事务
DataSourceUtils.startTransaction();
//2.调用dao层的操作order的方法
addOrders(order);
//3.调用dao层的操作orderitem的方法
addOrderItems(order);
} catch (SQLException e) {
//事务回滚
try {
DataSourceUtils.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
//提交释放资源
DataSourceUtils.commitAndRelease();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public void addOrders(Order order) throws SQLException{
QueryRunner runner = new QueryRunner();
String sql = "insert into orders values(?,?,?,?,?,?,?,?)";
Connection conn = DataSourceUtils.getConnection();
runner.update(conn, sql, order.getOid(),order.getOrdertime(),order.getTotal(),
order.getState(),order.getAddress(),order.getName(),
order.getTelephone(),order.getUser().getUid());
}
public void addOrderItems(Order order) throws SQLException{
QueryRunner runner = new QueryRunner();
Connection conn;
conn = DataSourceUtils.getConnection();
for(OrderItem item : order.getOrderItems())
{
String sql = "insert into orderitem values(?,?,?,?,?)";
runner.update(conn,sql,item.getItemid(),item.getCount(),item.getSubtotal(),
item.getProduct().getPid(),order.getOid());
}
}
7.提交订单
在订单页面中点击提交订单,此时就需要支付的接口了,这里用的是易宝支付的接口,点击提交订单的时候直接跳转到支付页面
protected void orderForm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//更新用户状态
HttpSession session = request.getSession();
Order order = (Order) session.getAttribute("order");//获取订单
//获取姓名,地址,电话,封装到order里面
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone");
order.setAddress(address);
order.setTelephone(phone);
order.setName(name);
ps.updateOrder(order);//更改数据库的数据
//完成支付功能
// 2.完成支付功能
// 获得 支付必须基本数据
String orderid = order.getOid();
String money = "0.01";
// 银行
String pd_FrpId = request.getParameter("pd_FrpId");
// 发给支付公司需要哪些数据
String p0_Cmd = "Buy";
String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId");
String p2_Order = orderid;
String p3_Amt = money;
String p4_Cur = "CNY";
String p5_Pid = "";
String p6_Pcat = "";
String p7_Pdesc = "";
// 支付成功回调地址 ---- 第三方支付公司会访问、用户访问
// 第三方支付可以访问网址
String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("callback");
String p9_SAF = "";
String pa_MP = "";
String pr_NeedResponse = "1";
// 加密hmac 需要密钥
String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue");
String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc,
p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue);
String url = "https://www.yeepay.com/app-merchant-proxy/node?pd_FrpId=" + pd_FrpId + "&p0_Cmd=" + p0_Cmd
+ "&p1_MerId=" + p1_MerId + "&p2_Order=" + p2_Order + "&p3_Amt=" + p3_Amt + "&p4_Cur=" + p4_Cur
+ "&p5_Pid=" + p5_Pid + "&p6_Pcat=" + p6_Pcat + "&p7_Pdesc=" + p7_Pdesc + "&p8_Url=" + p8_Url
+ "&p9_SAF=" + p9_SAF + "&pa_MP=" + pa_MP + "&pr_NeedResponse=" + pr_NeedResponse + "&hmac=" + hmac;
// 重定向到第三方支付平台
response.sendRedirect(url);
}
当支付完成之后需要一个回调函数,将数据库中的订单改成已支付的状态
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获得回调所有数据
String p1_MerId = request.getParameter("p1_MerId");
String r0_Cmd = request.getParameter("r0_Cmd");
String r1_Code = request.getParameter("r1_Code");
String r2_TrxId = request.getParameter("r2_TrxId");
String r3_Amt = request.getParameter("r3_Amt");
String r4_Cur = request.getParameter("r4_Cur");
String r5_Pid = request.getParameter("r5_Pid");
String r6_Order = request.getParameter("r6_Order");
String r7_Uid = request.getParameter("r7_Uid");
String r8_MP = request.getParameter("r8_MP");
String r9_BType = request.getParameter("r9_BType");
String rb_BankId = request.getParameter("rb_BankId");
String ro_BankOrderId = request.getParameter("ro_BankOrderId");
String rp_PayDate = request.getParameter("rp_PayDate");
String rq_CardNo = request.getParameter("rq_CardNo");
String ru_Trxtime = request.getParameter("ru_Trxtime");
// 身份校验 --- 判断是不是支付公司通知你
String hmac = request.getParameter("hmac");
String keyValue = ResourceBundle.getBundle("merchantInfo").getString(
"keyValue");
// 自己对上面数据进行加密 --- 比较支付公司发过来hamc
boolean isValid = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd,
r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid,
r8_MP, r9_BType, keyValue);
if (isValid) {
// 响应数据有效
if (r9_BType.equals("1")) {
ProductService ps=new ProductService();
ps.updateOrderState(r6_Order);
// 浏览器重定向
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("<h1>付款成功!等待商城进一步操作!等待收货...</h1>");
} else if (r9_BType.equals("2")) {
// 服务器点对点 --- 支付公司通知你
System.out.println("付款成功!");
// 修改订单状态 为已付款
// 回复支付公司
response.getWriter().print("success");
}
} else {
// 数据无效
System.out.println("数据被篡改!");
}
}
8.我的订单
点击我的订单触发myOrder方法,订单实现了分页功能
首先得page为1
判断user是否为空。为空返回登录页面
protected void myOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String page = request.getParameter("page");
User user = (User) session.getAttribute("user");
BaseDao dao=new BaseDao();
if (user==null) {//判断用户是否为空
response.sendRedirect(request.getContextPath()+"/login.jsp");
return;
}
String uid=user.getUid();
//拿到用户的总的订单量
int orderCount = dao.getOrderCount(uid);
//将当前页码page,每页展示的数据个数,总的数据传入到pageBean中
PageBean<Order> pageBean=new PageBean<Order>(Integer.parseInt(page),6,orderCount);
pageBean.setCid(uid);
//获取该用户的所有订单
List<Order> orders = ps.getOrders(user.getUid(),pageBean);
if (orders!=null) {
for (Order order : orders) {
//获取每一个订单 根据oid查找订单项集合
try {
//sql = "select i.count,i.subtotal,p.pimage,p.pname,p.shop_price from "
// + "orderitem i,product p where i.pid=p.pid and i.oid=?";
//获取需要展示的数据,存放到list嵌套Map的集合中
List<Map<String,Object>> orderItems = ps.getOrderItems(order.getOid());
for (Map<String, Object> map : orderItems) {
OrderItem orderItem=new OrderItem();
BeanUtils.populate(orderItem, map); //将数据映射到orderItem中
Product pro=new Product();
BeanUtils.populate(pro, map);//将数据映射到product中
orderItem.setProduct(pro); //Pro添加到orderItem中
order.getOrderItems().add(orderItem);//orderItem添加到Order中
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
pageBean.setData(orders);
request.setAttribute("pageBean", pageBean);
request.getRequestDispatcher("/order_list.jsp").forward(request, response);
}
public List<Map<String, Object>> getOrderItems(String oid ) throws SQLException{
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "select i.count,i.subtotal,p.pimage,p.pname,p.shop_price from "
+ "orderitem i,product p where i.pid=p.pid and i.oid=?";
List<Map<String, Object>> listMap = runner.query(sql, new MapListHandler(), oid);
return listMap;
}
五、后台
后台管理只有三个模块1.分类管理,2.商品管理,3.订单管理,实现的是增删改查的功能
1.登录
数据库中创建admin表,存放管理员信息
简单的登录流程,是简化的前台登录。
2.分类管理
A 分类列表
当点击分类管理时,从数据库中获取商品分类列表展示在list.jsp页面上
public void queryCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
List<Category> categoryList = service.queryCategory();//获取所有的商品分类
request.setAttribute("categoryList", categoryList);
request.getRequestDispatcher("/admin/category/list.jsp").forward(request, response)
}
<c:forEach items="${categoryList }" var="category">
<tr onmouseover="this.style.backgroundColor = 'white'"
onmouseout="this.style.backgroundColor = '#F5FAFE';">
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="18%">${category.cid }</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="17%">${category.cname }</td>
<td align="center" style="HEIGHT: 22px"><a
href="${ pageContext.request.contextPath }/admin/category/edit.jsp?cid=${category.cid}&cname=${category.cname}">
<img
src="${pageContext.request.contextPath}/images/i_edit.gif"
border="0" style="CURSOR: hand">
</a></td>
<td align="center" style="HEIGHT: 22px"><a
href="${pageContext.request.contextPath}/admin/AdminServlet?state=delete&cid=${category.cid}">
<img src="${pageContext.request.contextPath}/images/i_del.gif"
width="16" height="16" border="0" style="CURSOR: hand">
</a></td>
</tr>
</c:forEach>
B 编辑
当点击编辑的时候,进入编辑页面,并将更改的数据回显到编辑页面(传入参数cid和cname,在edit.jsp页面找显示数据),点击确定是触发edit方法,最后返回商品分类列表
protected void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cname = request.getParameter("cname");
String cid = request.getParameter("cid");
service.updateCategory(cid, cname);
queryCategory(request, response);
}
C 删除
protected void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cid = request.getParameter("cid");
service.deleteCategory(cid);
queryCategory(request, response);
}
D 添加
点击添加时,进入add.jsp页面,点击确定,将数据添加到数据库,在返回到商品分类列表中
protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cname = request.getParameter("cname");
Category category=new Category();
category.setCname(cname);
category.setCid(StringUtils.getUUID());
int i=service.insertCategory(category);
queryCategory(request, response);
}
3.商品管理
商品管理中基本的和分类管理一样,应该说的是上传文件,在添加和编辑的时候都涉及到了
下面是添加的代码
protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 定义一个文件项工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
// 指定一个临时目录缓冲区
String temp_path = this.getServletContext().getRealPath("temp");
File file = new File(temp_path);
if (!file.exists()) {
file.mkdirs();
}
// 设置你的缓冲区大小
factory.setSizeThreshold(1024 * 1024);
// 设置缓冲区的位置
factory.setRepository(file);
ServletFileUpload upload = new ServletFileUpload(factory);
// 处理上传乱码的问题
upload.setHeaderEncoding("utf-8");
// 创建一个map集合,存储循环遍历数据的名值对
Map<String, String> map = new HashMap<String, String>();
//获取所有的表单信息存放到list中
List<FileItem> parseRequest = upload.parseRequest(request);
//遍历表单集合
for (FileItem fileItem : parseRequest) {
if (fileItem.isFormField()) {// 判断是否是一个普通表单
//获取表单名name
String fieldName = fileItem.getFieldName();
//获取表单值,编码格式转化为utf-8
String fieldValue = fileItem.getString("utf-8");
//将表单的信息存放到map集合中
map.put(fieldName, fieldValue);
} else {//如果不是普通表单,那就是上传文件
//拿到表单的name
String fieldName = fileItem.getFieldName();
// 拿到要上传文件的文件名
String fileName = fileItem.getName();
// 通过输入流拿到数据
InputStream input = fileItem.getInputStream();
// 把输入的内容(其实就是你要上的文件,写到指定的位置
fileItem.write(new File("D:\\newspace\\shop02\\WebContent\\products\\" + fileName));
// 写完之后,需要知道文件上传到什么位置了
map.put(fieldName, "products/" + fileName);
input.close();
fileItem.delete();
}
}
Product product = new Product();
BeanUtils.populate(product, map);//将表单中的数据映射到product里面
product.setPid(StringUtils.getUUID());
product.setPflag(0);
product.setPdate(StringUtils.getDate());
service.insertProduct(product);//将商品存放到数据库中
queryProduct(request, response);//返回商品列表
} catch (Exception e) {
e.printStackTrace();
}
}
编辑的代码
protected void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String pid = request.getParameter("pid");
String pimage = request.getParameter("pimage");
// 定义一个文件项工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
// 指定一个临时目录缓冲区
String temp_path = this.getServletContext().getRealPath("temp");
File file = new File(temp_path);
if (!file.exists()) {
file.mkdirs();
}
// 设置你的缓冲区大小
factory.setSizeThreshold(1024 * 1024);
// 设置缓冲区的位置
factory.setRepository(file);
ServletFileUpload upload = new ServletFileUpload(factory);
// 处理上传乱码的问题
upload.setHeaderEncoding("utf-8");
// 创建一个map集合,存储循环遍历数据的名值对
Map<String, String> map = new HashMap<String, String>();
List<FileItem> parseRequest = upload.parseRequest(request);
for (FileItem fileItem : parseRequest) {
if (fileItem.isFormField()) {// 判断是否是一个普通表单
String fieldName = fileItem.getFieldName();
String fieldValue = fileItem.getString("utf-8");
map.put(fieldName, fieldValue);
} else {
String fieldName = fileItem.getFieldName();
// 拿到要上传文件的文件名
String fileName = fileItem.getName();
if (fileName.equals("")) {//如果没有上传文件,就继续用以前的文件
fileName = pimage;
map.put(fieldName, fileName);
} else {//如果上传了文件,就改变以前的图片
// 通过输入流拿到数据
InputStream input = fileItem.getInputStream();
// 把输入的内容(其实就是你要上的文件,写到指定的位置
fileItem.write(new File("D:\\newspace\\shop02\\WebContent\\products\\" + fileName));
// 写完之后,需要知道文件上传到什么位置了
map.put(fieldName, "products/" + fileName);
input.close();
fileItem.delete();
}
}
}
Product product = new Product();
BeanUtils.populate(product, map);
product.setPid(pid);
product.setPflag(0);
product.setPdate(StringUtils.getDate());
service.updatePro(product);
queryProduct(request, response);
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
4.订单管理
订单管理只有查看的功能,可以查看每个订单的订单项,这里用到了ajax技术,当点击订单详情的时候展示出每个订单的订单项,要记得导入插件呢
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String state = request.getParameter("state");
if (state.equals("orderList")) {
orderList(request, response);
}else if (state.equals("findOrderInfoByOid")) {
findOrderInfoByOid(request, response);
}
}
protected void orderList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Order> orderList = as.getOrderList();
request.setAttribute("orderList", orderList);
request.getRequestDispatcher("/admin/order/list.jsp").forward(request, response);
}
protected void findOrderInfoByOid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String oid = request.getParameter("oid");
List<Map<String, Object>> orderItemByOid = as.getOrderItemByOid(oid);
Gson g=new Gson();
String json = g.toJson(orderItemByOid);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(json);
}
<script type="text/javascript">
$(function(){
//弹出层插件调用
new PopupLayer({
trigger:".clickedElement",//触发对象
popupBlk:"#showDiv",//弹出层是哪个DIV
closeBtn:"#closeBtn",//关闭弹出层点击哪个元素
useOverlay:true
});
});
function findOrderInfoByOid(oid)
{
//清空显示的详情内容
$("#showDivTab").html("");
$("#shodDivOid").html(oid);
//设置加载图片显示
$("#loading").css({"display":"block"});
$.post(
"${pageContext.request.contextPath}/admin/OrderServlete?state=findOrderInfoByOid",
{"oid":oid},
function(data){
$("#loading").css({"display":"none"});
//[
//{"shop_price":2299.0,"count":2,"pname":"宏碁(acer)ATC705-N50 台式电脑","pimage":"products/1/c_0031.jpg","subtotal":4598.0},
//{"shop_price":1299.0,"count":4,"pname":"小米 4c 标准版","pimage":"products/1/c_0001.jpg","subtotal":5196.0},
//{"shop_price":2298.0,"count":1,"pname":"vivo X5Pro","pimage":"products/1/c_0014.jpg","subtotal":2298.0}
//]
var content=
"<tr id='showTableTitle'>"+
"<th width='20%'>图片</th>"+
"<th width='25%'>商品</th>"+
"<th width='20%'>价格</th>"+
"<th width='15%'>数量</th>"+
"<th width='20%'>小计</th>"+
"</tr>"
for(var i in data)
{
content+="<tr style='text-align: center;'>"+
"<td><img src='${pageContext.request.contextPath }/"+data[i].pimage+"' width='70' height='60'></td>"+
"<td><a target='_blank'>"+data[i].pname+"</a></td>"+
"<td>¥"+data[i].shop_price+"</td>"+
"<td>"+data[i].count+"</td>"+
"<td><span class='subtotal'>¥"+data[i].subtotal+"</span></td></tr>";
}
$("#showDivTab").html(content);
},
"json"
)
}
</script>
public List<Map<String,Object>> getOrderItemByOid(String oid){
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql="select p.pimage,p.pname,p.shop_price,i.count,i.subtotal from orderitem i,product p where i.pid=p.pid and i.oid=?";
List<Map<String,Object>> query=null;
try {
query = runner.query(sql, new MapListHandler(), oid);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return query;
}