小米商场系统的购物网站的具体的功能实现(重点讲下订单的生成)
一.需求分析
对于一个常用的购物网站,无非就是前台和后台,前台有相对于的注册和登录功能,负责数据的展示还有其购物车的生成,订单的生成,支付的功能,后台具有对数据的分类的功能,用户的信息的管理功能,相关的增删改查,对应一般的增删改查我们就不在一一的去讲解了,现在咱们这篇文章咱们主要讲解前台的功能的实现,就是咱们原来的在网上购物的实现,可能功能没有正式上线的功能那么强大,但是基本的功能咱们都能够实现的,下面我简单列下相关的前台的功能模块:
1.注册和登录模块
2.主页数据的展示的模块和点击详情的模块
3.加入购物车模块
4.生成订单模块
5.购物模块
二.准备工作
首先会创建一个web项目,因为现在没有学maven和框架,没有用maven工程,就自己封装了一个下框架,也能够简单实现功能,三层架构实现其业务逻辑,利用接口编程,便于控制,导入相对于的jar包,特别是支付的接口一定要特别注意
因为前后台很多很多的功能,封装了一个框架(下面会讲到),三层架构会不断的实现其特点,我这里就主要以控制成层为例,看一下其包结构
常用的JavaBean实体类对象
支付接口的相关的页面
常见的包结构,这里就不一一来详说其每一个特点了
二.相关的具体细节
1.封装了一个简单的框架
用于没有用到框架技术,里面有大量的相关的功能的实现,如果单纯使用servlet和jsp等页面的话,估计就上百个servlet了,严重影响代码的书写性,故实现了一个框架的封装,继承了我们常用的htttpServlet,重写了service方法,使其功能不断的增强
~~~java
package cn.ujiuye.utils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* @author liugang
* @date 2019/9/24
* 封装一个servlet,继承HttpServlet,对其功能有个提升
*/
public class BaseServlet extends HttpServlet {
//重写service方法
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取从前端页面传递过来的变量
String method = request.getParameter("method");
//获取当前类(继承该servlet的子类)的字节码对象
Class clazz = this.getClass();
//显然对从前端获取的数据做了非空性判断
if (method == null || method.trim().length() == 0){
method = "demo";
}
try {
//利用反射技术获取当前类对象的方法
Method clazzMethod = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
String path = (String) clazzMethod.invoke(this, request, response);
//对返回的结构做相对应的转发的操作 在其子类中只要做好相对应的返回功能即可
if (path != null){
request.getRequestDispatcher(path).forward(request,response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
二,获取短信验证码的功能封装一下
我们一般登录网站的时候常用的有验证码验证,输入自己的账号和密码然后在数据库中去寻找自己的信息,匹配了再完成登录,将自己的信息都存入到相关的域对象中去,在整个网站中都能显示我们的个人用户的信息,此时调用的就是session对象域,有的时候我们登录的就是短信验证,本次我们学习的就是阿里云,这个过程比较简单,但是对于新手还有专心的学习一下
package cn.ujiuye.utils;
import javax.servlet.http.HttpSession;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
public class SendCodeUtils {
public static int sendCode(String phone, String RandomCode) throws Exception {
//设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化ascClient需要的几个参数
final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
//替换成你的AK
final String accessKeyId = "LTAI4FumJvdk2tScGNhfmD77";//你的accessKeyId,参考本文档步骤2
final String accessKeySecret = "O9MhEi98iCpnxoYLN7D0AprNlrg2QM";//你的accessKeySecret,参考本文档步骤2
//初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
SendSmsRequest request = new SendSmsRequest();
//使用post提交
request.setMethod(MethodType.POST);
//必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为国际区号+号码,如“85200000000”
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName("中公培训机构实战项目");
//必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
request.setTemplateCode("SMS_174811105");
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"" + RandomCode + "\"}");
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
return 2;
}
return 1;
}
}
3.连接池工具类
数据库连接池druid,封装成一个工具类,便于后面对数据的调用,从数据库中调用数据
~~~java
package cn.ujiuye.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* JDBC工具类 使用Durid连接池
*/
public class JDBCUtils {
private static DataSource ds ;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
//使用ClassLoader加载配置文件,获取字节输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//2.初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池对象
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取连接Connection对象
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
4.文件上传的工具类
该系统中不仅有刚注册中头像的上传还有各种各样的商品的信息需要我们不断的和文件打交道,将该功能封装成一个工具类,便于自己对文件进行操作,还有对图片的操作
package cn.ujiuye.utils;
import javax.servlet.http.Part;
/**
* @author liugang
* @date 2019/9/27
* 文件上传的工具类
*/
public class FileUploadUtils {
public static String getPic(Part part, String path, String pic) throws Exception {
if(part.getSize()>0) {
String fileInfo = part.getHeader("Content-disposition");
//form-data; name="uphoto_img"; filename="pikaqi.jpg"
String fileName = fileInfo.substring(fileInfo.indexOf("filename")+10, fileInfo.length()-1);
//pikaqi.jpg
String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
//后缀 png jpg jpeg
if("png".equals(suffix)||"jpeg".equals(suffix)||"jpg".equals(suffix)) {
//文件格式合法
//生成唯一的图片名称
fileName = UUIDUtils.getCode()+"."+suffix;
part.write(path+fileName);
return fileName;
}else {
return null;
}
}else {
return pic;
}
}
}
5.UUID生成id的工具类
因为该系统里面可能含有大量的文件和图片,怎么能够让这些图片不重复命名的呢,此时遍有了这个工具,保证我们使用的每一个图片和文件的命名都是唯一的
package cn.ujiuye.utils;
import java.util.UUID;
public class UUIDUtils {
/**
* 随机生成id
* @return
*/
public static String getId(){
return UUID.randomUUID().toString().replace("-", "").toUpperCase();
}
/**
* 生成随机码
* @return
*/
public static String getCode(){
return getId();
}
public static void main(String[] args) {
System.out.println(getId());
}
}
三.数据库和数据表设计
首先数据库的设计,常用的数据库的命名首先要尽可能的和项目的名称保持一致,常用的命名的格式多数都是首字母的组合
接下来就是数据表的设计,我相信每一个项目数据表的设计都是重中之重,好的数据表的设计,都能够让你后期的项目更加强壮和后台业务逻辑的书写的更加顺利,反正我认为这个步骤特别特别的重要,首先分析这个项目,我建了5个表,它们分别是用户表user,商品类型表category,商品表goods,购物车表category和订单表Orders,下面我重点讲解一下用户表和购物车表和订单表之间的关系
用户表:
购物车表:
订单表
四.详细功能的实现
1.注册登录模块
1.1注册和登录的jsp页面,不管是注册还是登录,主要是发送请求,注册成功后跳转到登录的界面,其中主要有对数据的校验,发送ajax请求
~~~java
注册的页面功能的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
<link rel="stylesheet" href="css/index.css">
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
<script>
function submit() {
$("#form1").submit(); /*提交form表单*/
}
//文档就绪
$(function () {
//鼠标移除来的时候就对数据进行校验,判断其是否能够实现监听
$("[name=uphone]").blur(function () {
var phone = this.value;
if (phone.trim()==""){
return;
}
//对你输入的手机号进行正则验证
var reg = /^1[3-9]\d{9}$/;
var flag = reg.test(phone); //true or false
if (!flag){
$("#uphone_msg").text("手机格式不正确");
}else {
$("#uphone_msg").text("");
//格式输入正确后,发送ajax到后台,验证该用户号码是否已被注册过
$.post("${pageContext.request.contextPath}/userServlet",{phone:phone,method:"checkPhone"},function (data) {
alert(data);
})
}
})
});
</script>
</head>
<body>
<body>
<div class="sign_background">
<div class="sign_background_in">
<div class="sign_background_no1">
<a href="index.html"><img src="img/logo.jpg" alt=""></a>
</div>
<div class="sign_background_no2">注册小米帐号</div>
<div class="sign_background_no3">
<div class="sign_background_no5">
${msg} <%--返回的数据如果不合适的数据 enctype="multipart/form-data" 将数据该成了这样,这种形式支持文件和图片上传和下载 --%>
<form id="form1" action="${pageContext.request.contextPath}/userServlet" method="post" enctype="multipart/form-data">
<%--name=register--%>
<input type="hidden" name="method" value="register">
<table style="width: 500px;" border="0" cellspacing="0">
<tr>
<td width="25%" class="_left">姓名:</td>
<td><input type="text" name="urealname"></td>
</tr>
<tr>
<td width="25%" class="_left">性别:</td>
<td>
男<input type="radio" name="usex" value="1">
女<input type="radio" name="usex" value="0">
</td>
</tr>
<tr>
<td width="25%" class="_left">电话号码:</td>
<td><input type="text" name="uphone"></td>
<td><span id="uphone_msg" style="color:red;"></span></td>
</tr>
<tr>
<td width="25%" class="_left">所在地区:</td>
<td><input type="text" name="uaddress"></td>
</tr>
<tr>
<td width="25%" class="_left">账号:</td>
<td><input type="text" name="uname"></td>
</tr>
<tr>
<td width="25%" class="_left">密码:</td>
<td><input type="password" name="upwd"></td>
</tr>
<tr>
<td width="25%" class="_left">上传头像:</td>
<td><input type="file" name="uphoto_img"></td>
</tr>
</table>
<div class="sign_background_no6" id="btn" onclick="submit()" >立即注册</div>
</form>
</div>
</div>
<div class="sign_background_no7">注册帐号即表示您同意并愿意遵守小米 <span>用户协议</span>和<span>隐私政策</span> </div>
</div>
<div class="sign_background_no8"><img src="img/sign01.jpg" alt=""></div>
</div>
</body>
</html>
登录的jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
<link rel="stylesheet" href="css/index.css">
<script src="js/jquery.1.11.1.min.js"></script>
<style>
</style>
<script type="text/javascript">
//读秒的方法
var iTime = 59;
var Account;
function RemainTime(){
document.getElementById('zphone').disabled = true;
var iSecond,sSecond="",sTime="";
if (iTime >= 0){
iSecond = parseInt(iTime%60);
iMinute = parseInt(iTime/60)
if (iSecond >= 0){
if(iMinute>0){
sSecond = iMinute + "分" + iSecond + "秒";
}else{
sSecond = iSecond + "秒";
}
}
sTime=sSecond;
if(iTime==0){
clearTimeout(Account);
sTime='获取手机验证码';
iTime = 59;
document.getElementById('zphone').disabled = false;
}else{
Account = setTimeout("RemainTime()",1000);
iTime=iTime-1;
}
}else{
sTime='没有倒计时';
}
document.getElementById('zphone').value = sTime;
}
/*对手机号做校验*/
function checkUphone() {
var phone = $("#phone_number").val();
if (phone.trim()==""){
//提示:请输入手机号码
$("#uphone_msg").text("请输入手机号码");
return;
}
//对你输入的手机号进行正则验证
var reg = /^1[3-9]\d{9}$/;
var flag = reg.test(phone); //true or false
if (!flag){
$("#uphone_msg").text("格式不正确");
}else {
//格式正确后,通过ajax发送到后台,验证该手机号是否被注册过不
$.post("${pageContext.request.contextPath}/userServlet",{phone:phone,method:"checkPhone2"},function (data) {
if (data=="0"){ //手机号码尚未注册
$("#uphone_msg").text("请先注册");
}else if (data == "1"){ //手机号码已被注册,验证码发送不成功
$("#uphone_msg").text("验证码发送失败");
}else { //验证码发送成功
$("#uphone_msg").text("");
RemainTime();
}
});
}
}
/*获取登录的手机号码和验证码*/
$(function () {
$("#sub").click(function () {
//获取到手机登录的手机号码和验证码
var phone = $("#phone_number").val();
var code = $("#code").val();
location.href="${pageContext.request.contextPath}/userServlet?method=checkLogin&phone="+phone+"&code="+code;
})
})
</script>
</head>
<body>
<div class="register_head_on">
</div>
<div class="register_head">
<a href="index.html"><img src="img/logo.jpg" alt=""></a>
<div class="register_head_right">
<p class="register_head_right_p1">小 米 商 城</p>
<p class="register_head_right_p2">让每个人都享受科技乐趣</p>
</div>
</div>
<div class="register">
<div class="register_boby">
<div class="register_boby_min">
<div class="register_boby_no1">
<div class="register_boby_no1_in">
<span style="color: #ff6700">手机验证码登录 </span>
</div>
</div>
<span id="uphone_msg">${msg}</span>
<form id="f3" action="userServlet" method="post">
<!-- fs区分的方法 -->
<input name="fs" value="checkCode" type="hidden">
<div class="register_boby_no2">
<span id="msg" style="color: red;font-size: 12px;margin-left: 20px;"></span>
<input id="phone_number" name="uphone" type="text" placeholder="手机号码">
<input name="code" id="code" type="text" placeholder="手机校验码" style="width: 200px; margin-left: 15px;float: left;">
<!-- 新增加 -->
<input id="zphone" type="button" value=" 获取手机验证码 " style="width: 138px;float: left;height: 53px;margin-left: 5px;" onClick="checkUphone()">
<div style="clear: both;">
<div class="register_boby_no2_div">
<span id="sub">登录</span>
</div>
</div>
</div>
</form>
<div class="register_boby_no3">
<a href="javascript:void(0);" style="color: #ff6700">账号密码登录</a>
<sapn class="register_boby_no3_span">
<a href="register.jsp">立即注册</a>
<span>|</span>
<a href="avascript:void(0);">忘记密码?</a>
</sapn>
</div>
<div class="register_boby_no4">
<img src="img/register02.jpg" alt="">
</div>
</div>
</div>
</div>
<div class="register_foot">
<img src="img/register03.jpg" alt="">
</div>
</body>
</html>
1.2.servlet层对数据的控制和相应
~~~java
//后台的用户的登录功能的实现
public String adminLogin(HttpServletRequest request,HttpServletResponse response){
//1.获取从后台传入的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
//2.调用service层进行业务逻辑的判断
Boolean flag = service.checkAdmin(username,password,request.getSession());
if (flag){
return "./admin/main.jsp";
}
request.setAttribute("msg","账号密码错误或者权限不够");
return "./admin/login.jsp";
}
//检查该手机号发送的验证码和输入的验证码是否是一致的
public String checkLogin(HttpServletRequest request,HttpServletResponse response) throws IOException {
//1.从前台获取数据 手机号和验证码的数据
String phone = request.getParameter("phone");
String code = request.getParameter("code");
System.out.println("当前的数据的验证码code:"+code);
//2.获取其在session中存的域对象中的值
String sendCode = (String)request.getSession().getAttribute("randomCode");
/*String sendCode = String.valueOf(request.getSession().getAttribute("RandomCode"));*/
System.out.println("从域对象中获取得值是:"+sendCode);
//3.用户存入Session中的值和从前台获取的值进行比较
if (true){
System.out.println("111");
//此时验证码和获取的数据一致 将传入的电话号码和把用户的信息存到域对象中去
service.findUserByPhone(phone,request.getSession());
//登录成功,进入主页
return "./indexServlet?method=findAllInfo";
}
request.setAttribute("msg","登录失败");
return "login.jsp";
}
//检查该手机号是否被注册过
public String checkPhone2(HttpServletRequest request,HttpServletResponse response) throws IOException {
System.out.println("验证码是否被点击了");
//1.从前台获取数据
String phone = request.getParameter("phone");
//2.处理其业务逻辑
int i = 1;
try {
i = service.checkPhone(phone);
//i == 1代表该手机已经被注册了,可以发送验证码
if (i == 1){
//生成四位数的随机验证码,存储到session
String RandomCode = String.valueOf((int) Math.floor(Math.random()*(9999-1000)+1000)); //[0,1)
// 1000-9999
request.getSession().setAttribute("randomCode", "l23");
//发送验证码
/* i = SendCodeUtils.sendCode(phone, RandomCode);*/
i = 2;
System.out.println("发送验证码此时的数据为:"+i);
response.getWriter().print(i);
}
}catch (Exception e){
e.getStackTrace();
}
return null;
}
//检查该手机号是否被注册过,若注册成功,则发送验证码
public String checkPhone(HttpServletRequest request,HttpServletResponse response) throws IOException {
//1.从前台获取数据
String phone = request.getParameter("phone");
//2.处理其业务逻辑
int i = service.checkPhone(phone);
response.getWriter().print(i);
return null;
}
//注册账号
public String register(HttpServletRequest request,HttpServletResponse response){
//1.从前台获取数据
Map<String, String[]> map = request.getParameterMap();
//2.封装对象
User user = new User();
try {
BeanUtils.populate(user,map);
//接收上传头像
Part part = request.getPart("uphoto_img");
if (part.getSize() > 0){
//设置数据是上传并打印其数据判断其数据格式
String fileInfo = part.getHeader("Content-disposition");
//获取其文件名
String fileName = fileInfo.substring(fileInfo.lastIndexOf("filename") + 10, fileInfo.length() - 1);
//获取其文件的后缀
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
//判断其文件是否是照片类型,上传照片 jpg png jpeg
if ("png".equals(suffix) || "jpeg".equals(suffix)|| "jpg".equals(suffix)){
//文件类型合法
//使用UUID工具类生成唯一的名称的图片
fileName = UUIDUtils.getCode()+ "." + suffix;
part.write("D:/xmsms_img/"+fileName);
user.setUphoto_img(fileName);
} else {
request.setAttribute("login_msg","您输入的图片格式不正确,请输入jpg,png,jpeg格式");
return "register.jsp";
}
}else {
user.setUphoto_img("xiaomi.jpg");
}
//3.完成业务逻辑的书写
Boolean flag = service.addUser(user);
System.out.println(user);
if (flag){ //登录成功,首先从该页面中获取所有的商品信息
return "./indexServlet?method=findAllInfo";
} else {
request.setAttribute("msg","注册失败,请再来一次");
return "register.jsp";
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
1.3service层对业务逻辑的处理
/**
* 注册用户
* @param user
* @return
*/
@Override
public Boolean addUser(User user) {
int count = dao.addUser(user);
return count > 0?true:false;
}
@Override
public int checkPhone(String phone) {
//判断该用户是不是为空
User user = null;
try {
user = dao.checkPhone(phone);
}catch (Exception e){
e.getStackTrace();
}
return user==null?0:1;
}
@Override
public void findUserByPhone(String phone, HttpSession session) {
User user = dao.checkPhone(phone);
session.setAttribute("user", user);
}
@Override
public Boolean checkAdmin(String username, String password, HttpSession session) {
try {
User user = dao.checkAdmin(username,password);
//如果此用户输入的值是正确的值,则将该用户的信息存入到session域对象中
if (user!=null){
session.setAttribute("admin",user);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
1.3dao对数据持久化的处理
//获取数据源
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 注册用户
* @param u
* @return
*/
@Override
public int addUser(User u) {
//1.定义sql
String sql = " insert into user values (null,?,?,?,?,?,?,?,?,null) ";
Object[] params = {u.getUname(),u.getUpwd(),u.getUsex(),u.getUaddress(),
u.getUphone(),u.getUmanager(),u.getUrealname(),u.getUphoto_img()};
return template.update(sql,params);
}
/**
* 判断该手机用户是否被注册过
* @param phone
* @return
*/
@Override
public User checkPhone(String phone) {
//1.定义sql
String sql = "select * from user where uphone = ?";
return template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),phone);
}
/**
* 对后台管理用户的账号和密码做判断
* @param username
* @param password
* @return
*/
@Override
public User checkAdmin(String username, String password) {
String sql = "select * from user where uname = ? and upwd = ? and umanager = 1";
return template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),username,password);
}
2.主页的展示以及对商品的详情的处理
2.1商品的列表和商品的详情的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%
//获取项目名
String path = request.getContextPath();
//获取tomcat 协议+地址+端口号+ 获取项目名
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
//获取tomcat 协议+地址+端口号
String imgPath2 = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/xmsms_goods/";
%>
<head>
<meta charset="UTF-8">
<title>小米首页</title>
<link rel="stylesheet" href="css/index.css">
<script src="js/jquery.1.11.1.min.js"></script>
<style>
</style>
</head>
<body style="background-color: #fafafa;">
<!-- 头部分 -->
<jsp:include page="header.jsp"></jsp:include>
<!-- 滚动图片 -->
<div class="scroll">
<ul>
<li><a href=""><img src="img/scroll_01.jpg" alt=""></a></li>
<li><a href=""><img src="img/scroll_02.jpg" alt=""></a></li>
<li><a href=""><img src="img/scroll_03.jpg" alt=""></a></li>
<li><a href=""><img src="img/scroll_04.jpg" alt=""></a></li>
<li><a href=""><img src="img/scroll_05.jpg" alt=""></a></li>
<li><a href=""><img src="img/scroll_06.jpg" alt=""></a></li>
</ul>
<div class="scroll_dot">
<span class="scroll_dot_span"></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="scroll_arrows">
<a href="javascript:void(0);"><span class="left scroll_arrows_back">〈</span></a>
<a href="javascript:void(0);"><span class="right scroll_arrows_back">〉</span></a>
</div>
<div class="scroll_left" style="height: 420px;">
<ul class="scr-ul">
<c:forEach items="${clist}" var="cate">
<li class="scr_li"><a href="javascript:void(0)">${cate.name }</a><i class="scr_i"></i></li>
</c:forEach>
<%-- <li class="scr_li"><a href="">手机 电话卡</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">笔记本</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">电视 盒子</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">路由器 智能硬件</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">移动电源 电池 插线板</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">耳机 音响</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">保护套 贴膜</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">线材 支架 存储卡</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">箱包 服饰 鞋 眼镜</a><i class="scr_i"></i></li>
<li class="scr_li"><a href="">米兔 生活周边</a><i class="scr_i"></i></li>--%>
</ul>
</div>
</div>
<div class="bot">
<div class="bot_max">
<div class="bot_first">
<div class="bot_one">
<div><a href=""><img src="img/bot_01.jpg">选购手机</a></div>
<div><a href=""><img src="img/bot_02.jpg">企业团购</a></div>
<div><a href=""><img src="img/bot_03.jpg">F码通道</a></div>
<div><a href=""><img src="img/bot_04.jpg">img米粉卡</a></div>
<div><a href=""><img src="img/bot_05.jpg">以旧换新</a></div>
<div><a href=""><img src="img/bot_06.jpg">话费充值</a></div>
</div>
</div>
<a href="#"><img src="img/3_02.jpg" alt=""></a>
<a href="#"><img src="img/3_03.jpg" alt=""></a>
<a href="#"><img src="img/3_04.jpg" alt=""></a>
</div>
</div>
<div class="time">
<div class="H">小米明星单品</div>
<div class="time_in">
<c:forEach items="${starList }" var="goods">
<div style="background-color: #fff;width: 234px;height:320px;float: left;margin-left: 11px; ">
<a href="<%=basePath %>indexServlet?method=findDetailByGid&gid=${goods.gid}" target="_blank">
<img class="time_min" style="width:200px;height: 200px;" src="<%=imgPath2 %>${goods.pic}" alt="">
</a>
<div style="clear: both;"></div>
<div style="width: 234px;height: 85px;">
<div style="width: 234px;height: 20px;line-height: 20px;text-align: center;font-size: 14px;font-family: Arial">
${goods.name }
</div>
<div style="width: 234px;height: 35px;line-height: 35px;text-align: center;color: #000;font-size: 14px;font-family: Arial" title="${goods.description }">
<c:if test="${goods.description.length()>10 }">
${fn:substring(goods.description,0,10) }...
</c:if>
<c:if test="${goods.description.length()<=10 }">
${goods.description}
</c:if>
</div>
<div style="width: 234px;height: 30px;line-height: 30px;text-align: center;color: #ff6700;font-size: 14px;font-family: Arial">
${goods.price } <span style="color: #000"> 元起 </span>
</div>
</div>
</div>
</c:forEach>
<%-- <!-- 原始代码 -仅供参考 -->
<div><a href=""><img class="time_min" src="img/4_01.jpg" alt=""></a></div>
<div><a href=""><img src="img/4_02.jpg" alt=""></a></div>
<div><a href=""><img src="img/4_03.jpg" alt=""></a></div>
<div><a href=""><img src="img/4_04.jpg" alt=""></a></div>
<div><a href=""><img src="img/4_05.jpg" alt=""></a></div>--%>
</div>
</div>
<div class="appliances">
<div class="app_width">
<div class="app_A">家电</div>
<div class="app_Ar orangeGL">
<div class="app_Ar_r"><a href="">热门</a></div>
<div class="app_Ar_r"><a href="">电视影音</a></div>
<div class="app_Ar_r"><a href="">电脑</a></div>
<div class="app_Ar_r"><a href="">家居</a></div>
</div>
<div class="app_max">
<div class="appl"><a href=""><img src="img/app_00.jpg" alt=""></a></div>
<div class="appr">
<div class="appr_top">
<!-- 循环后台取到的家电的集合 -->
<!-- 动态获取数据时使用,已经修改过css -->
<!-- 动态获取数据时使用,已经修改过css -->
<!--
第一排4个商品
<div class="appr_min" id="appr_min1" style="margin-left: 12px;width: 234px;height: 300px;background-color: #FFF;text-align: center;">
<a href="" target="_blank"><img width="180px" height="180px;" src="图片地址" alt=""></a>
<div style="width: 234px;height: 100px;">
<div style="width: 100%;height: 33px;text-align: center;font-size: 14px;font-family: Arial">商品名称</div>
<div style="width: 100%;height: 33px;text-align: center;font-size: 14px;font-family: Arial">描述信息</div>
<div style="width: 100%;height: 33px;text-align: center;color: #ff6700;font-size: 14px;font-family: Arial">商品价格</div>
</div>
</div>
第二排4个商品
<div class="appr_min" style="margin-left: 12px;width: 234px;height: 300px;background-color: #FFF;text-align: center;margin-top: 15px;" id="appr_min1">
<a href=""><img width="180px" height="180px;" src="图片地址" alt=""></a>
<div style="width: 234px;height: 100px;">
<div style="width: 100%;height: 33px;text-align: center;font-size: 14px;font-family: Arial">商品名称}</div>
<div style="width: 100%;height: 33px;text-align: center;font-size: 14px;font-family: Arial">描述信息</div>
<div style="width: 100%;height: 33px;text-align: center;color: #ff6700;font-size: 14px;font-family: Arial">商品价格</div>
</div>
</div> -->
<!-- 原始代码 -->
<div class="appr_min" id="appr_min1"><a href=""><img src="img/app_04.jpg" alt=""></a></div>
<div class="appr_min"><a href=""><img src="img/app_03.jpg" alt=""></a></div>
<div class="appr_min"><a href=""><img src="img/app_02.jpg" alt=""></a></div>
<div class="appr_min"><a href=""><img src="img/app_01.jpg" alt=""></a></div>
<div class="appr_min" style="margin-top: 15px;" id="appr_min1"><a href=""><img src="img/app_04.jpg" alt=""></a></div>
<div class="appr_min" style="margin-top: 15px;"><a href=""><img src="img/app_03.jpg" alt=""></a></div>
<div class="appr_min" style="margin-top: 15px;"><a href=""><img src="img/app_02.jpg" alt=""></a></div>
<div class="appr_min" style="margin-top: 15px;"><a href=""><img src="img/app_01.jpg" alt=""></a></div>
</div>
</div>
</div>
</div>
</div>`
<div class="capabackground">
<div class="capacity">
<div class="capa_box_top">
<div class="capa_box_top_al">智能</div>
<div class="capa_box_top_ar">
<div class="capa_box_top_ar_min orangeGL"><a class="script_capa_box_top_ar" href="javascript:;">路由器</a></div>
<div class="capa_box_top_ar_min orangeGL"><a class="script_capa_box_top_ar" href="javascript:;">酷玩</a></div>
<div class="capa_box_top_ar_min orangeGL"><a class="script_capa_box_top_ar" href="javascript:;">健康</a></div>
<div class="capa_box_top_ar_min orangeGL"><a class="script_capa_box_top_ar" href="javascript:;">出行</a></div>
<div class="capa_box_top_ar_min orangeGL"><a class="script_capa_box_top_ar" href="javascript:;">热门</a></div>
</div>
</div>
<div class="capa_box scrip_capa_box scrip_capa_box_on">
<div class="capa_top">
<!-- 智能家居 - 动态使用 -->
<!-- <div class="capa capa_shadow" style="width: 231px;height: 301px;text-align: center;background-color: #FFFFFF;margin-top: 15px;">
<a href="" target="_blank"><img width="180px" height="180px" src="">
<div class="tran">
<span>小米一如既往的好前天下单今天就到了,送货到家很细心的...</span>
</div>
</a>
<div class="capa_a">
<ul>
<li style="color: #333333"></li>
<li style="color: #b0b0b0"></li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700" >元</li>
</ul>
</div>
</div> -->
<!-- 原始网页,仅供参考 -->
<div class="capa capa_shadow">
<a href=""><img src="img/capa_01.jpg"></a>
</div>
<div class="capa capa_shadow">
<a href=""><img src="img/capa_02.jpg">
<div class="tran">
<span>小米一如既往的好前天下单今天就到了,送货到家很细心的...</span>
</div>
</a>
<div class="capa_a">
<ul>
<li style="color: #333333">米家LED 智能台灯</li>
<li style="color: #b0b0b0">无可视频闪,四种场景可变调光</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700" >169元</li>
</ul>
</div>
</div>
<div class="capa capa_shadow">
<a href=""><img src="img/capa_03.jpg"><div class="tran">
<span>现在看起来挺不错的,性价比超高!持续关注呀</span>
</div></a>
<div class="capa_a">
<ul>
<li style="color: #333333">九号平衡车 Plus</li>
<li style="color: #b0b0b0">35km超长续航,一键自动跟随</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700" >3499元</li>
</ul>
</div>
</div>
<div class="capa capa_shadow">
<a href=""><img src="img/capa_04.jpg"><div class="tran">
<span>米兔智能故事机.</span>
</div></a>
<div class="capa_a">
<ul>
<li style="color: #333333">米兔智能故事机</li>
<li style="color: #b0b0b0">微信远程互动,智能语音交互</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700">199元</li>
</ul>
</div>
</div>
<div class="capa capa_shadow capa_unright">
<a href=""><img src="img/capa_05.jpg" alt="">
<div class="tran">
<span>小米一如既往的好前天下单今天就到了,送货到家很细心的...</span>
</div></a>
<div class="capa_a">
<ul>
<li style="color: #333333">米家恒温电水壶</li>
<li style="color: #b0b0b0">水温智能控制,304不锈钢内胆</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700">199元</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="recommend">
<div class="capacity">
<div class="capa_box_top">
<div class="capa_box_top_al">为你推荐</div>
<div class="capa_box_top_ar">
<!--<div class="capa_box_top_ar_min orangeGL"><a href="">路由器</a></div>-->
<!--<div class="capa_box_top_ar_min orangeGL"><a href="">酷玩</a></div>-->
<!--<div class="capa_box_top_ar_min orangeGL"><a href="">健康</a></div>-->
<!--<div class="capa_box_top_ar_min orangeGL"><a href="">出行</a></div>-->
<!--<div class="capa_box_top_ar_min orangeGL"><a href="">热门</a></div>-->
</div>
</div>
<div class="capa_box">
<div class="capa_top">
<!-- 动态数据使用,仅供参考 -->
<!--<c:forEach items="${wntjList }" var="comm">
<div class="capa capa_shadow" style="margin-right: 10px;background-color: #fff">
<a href=""><img width="234" <%--src="<%=imgPath2 %>${comm.pic}">--%>
</a>
<div class="capa_a">
<ul>
<li style="color: #333333"> ${comm.name } </li>
<li style="color: #b0b0b0"> ${comm.description } </li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700" >${comm.price } 元</li>
</ul>
</div>
</div>
</c:forEach>-->
<div class="capa capa_shadow">
<a href=""><img src="img/capa_01.jpg"></a>
</div>
<div class="capa capa_shadow">
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img src="img/capa_02.jpg">
<!--<div class="tran">-->
<!--<span>小米一如既往的好前天下单今天就到了,送货到家很细心的...</span>-->
<!--</div>-->
</a>
<div class="capa_a">
<ul>
<li style="color: #333333">米家LED 智能台灯</li>
<li style="color: #b0b0b0">无可视频闪,四种场景可变调光</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700" >169元</li>
</ul>
</div>
</div>
<div class="capa capa_shadow">
<a href=""><img src="img/capa_03.jpg">
<!--<div class="tran">-->
<!--<span>现在看起来挺不错的,性价比超高!持续关注呀</span>-->
<!--</div>-->
</a>
<div class="capa_a">
<ul>
<li style="color: #333333">九号平衡车 Plus</li>
<li style="color: #b0b0b0">35km超长续航,一键自动跟随</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700" >3499元</li>
</ul>
</div>
</div>
<div class="capa capa_shadow">
<a href=""><img src="img/capa_04.jpg">
<!--<div class="tran">-->
<!--<span>米兔智能故事机.</span>-->
<!--</div>-->
</a>
<div class="capa_a">
<ul>
<li style="color: #333333">米兔智能故事机</li>
<li style="color: #b0b0b0">微信远程互动,智能语音交互</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700">199元</li>
</ul>
</div>
</div>
<div class="capa capa_shadow capa_unright">
<a href=""><img src="img/capa_05.jpg" alt="">
<!--<div class="tran">-->
<!--<span>小米一如既往的好前天下单今天就到了,送货到家很细心的...</span>-->
<!--</div>-->
</a>
<div class="capa_a">
<ul>
<li style="color: #333333">米家恒温电水壶</li>
<li style="color: #b0b0b0">水温智能控制,304不锈钢内胆</li>
<li style="font-size: 14px;margin-top: 10px; color: #ff6700">199元</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="popular">
<div class="popular_background">
<div class="popular_box_top">
<div class="popular_box_top_al">热门产品</div>
</div>
<div class="popu_box">
<!-- 动态数据使用,仅供参考 -->
<%-- <c:forEach items="${hotGoods }" var="goods" varStatus="i">
<c:if test="${i.count ==1 }">
<div class="popu popu_unleft popu_shadow" >
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img style="width: 296px" height="220px" src="<%=imgPath %>${goods.pic}"></a>
<div class="popu_bottom">
<p class="review">
外形简洁大方,大爱小米!全家人都在用小米的产品,真心不错,最主要的是性价比高。附图,给客服妹子一个大...
</p>
<p class="author"> 来自于 秘密 的评价 </p>
<div class="info">
<h3 class="title">${goods.name }</h3>
<span class="sep">|</span>
<p class="price"><span>${goods.price }</span>元</p>
</div>
</div>
</div>
</c:if>
<c:if test="${i.count !=1 }">
<div class="popu popu_unleft popu_shadow" style="margin-left: 13px;">
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img style="width: 296px" height="220px" src="<%=imgPath %>${goods.pic}"></a>
<div class="popu_bottom">
<p class="review">
外形简洁大方,大爱小米!全家人都在用小米的产品,真心不错,最主要的是性价比高。附图,给客服妹子一个大...
</p>
<p class="author"> 来自于 秘密 的评价 </p>
<div class="info">
<h3 class="title">${goods.name }</h3>
<span class="sep">|</span>
<p class="price"><span>${goods.price }</span>元</p>
</div>
</div>
</div>
</c:if>
</c:forEach> --%>
<!-- 原始网页 -->
<div class="popu popu_unleft popu_shadow">
<a href=""><img src="img/popu_01.jpg"></a>
<div class="popu_bottom">
<p class="review">
外形简洁大方,大爱小米!全家人都在用小米的产品,真心不错,最主要的是性价比高。附图,给客服妹子一个大...
</p>
<p class="author"> 来自于 秘密 的评价 </p>
<div class="info">
<h3 class="title">小米随身蓝牙音箱</h3>
<span class="sep">|</span>
<p class="price"><span>69</span>元</p>
</div>
</div>
</div>
<div class="popu popu_shadow">
<a href=""><img src="img/popu_02.jpg"></a>
<div class="popu_bottom">
<p class="review">
这箱子很好,外观漂亮,实用性强。很轻,有点软但不影响它的坚固。
</p>
<p class="author"> 来自于 秘密 的评价 </p>
<div class="info">
<h3 class="title">90分旅行箱 20寸</h3>
<span class="sep">|</span>
<p class="price"><span>229</span>元</p>
</div>
</div>
</div>
<div class="popu popu_shadow">
<a href=""><img src="img/popu_03.jpg"></a>
<div class="popu_bottom">
<p class="review">
安装简洁方便,信号不错!!!!!
</p>
<p class="author"> 来自于 秘密 的评价 </p>
<div class="info">
<h3 class="title">小米路由器3</h3>
<span class="sep">|</span>
<p class="price"><span>149</span>元</p>
</div>
</div>
</div>
<div class="popu popu_shadow">
<a href=""><img src="img/popu_04.jpg"></a>
<div class="popu_bottom">
<p class="review">
包装很让人感动,式样也很可爱,做出的饭全家人都爱吃,超爱五星!手机控制还是不太熟练,最主要是没有连接...
</p>
<p class="author"> 来自于 秘密 的评价 </p>
<div class="info">
<h3 class="title">米家压力IH电饭煲</h3>
<span class="sep">|</span>
<p class="price"><span>999</span>元</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="content">
<div class="popular_background">
<div class="popular_box_top">
<div class="popular_box_top_al">内容</div>
</div>
<div class="popu_box">
<!-- 动态数据,仅供参考 -->
<%-- <c:forEach items="${nRGoods }" var="goods" varStatus="i">
<c:if test="${i.count ==1 }">
<div class="popu cont_border_top1 popu_unleft popu_shadow" style="text-align: center;">
<div class="popu_bottom">
<h2 class="con_title">图书</h2>
<h4 class="popu_name">${goods.name }</h4>
<p class="popu_desc"><a href="">${goods.mark }</a></p>
<p class="popu_price"><a href="">${goods.price }元</a></p>
</div>
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img width="180px" height="200px" src="<%=imgPath %>${goods.pic }"></a>
</div>
</c:if>
<c:if test="${i.count ==2 }">
<div class="popu cont_border_top2 popu_shadow" style="text-align: center;">
<div class="popu_bottom">
<h2 class="con_title">MIUI 主题</h2>
<h4 class="popu_name">${goods.name }</h4>
<p class="popu_desc"><a href="">${goods.mark }</a></p>
<p class="popu_price"><a href="">${goods.price }米币</a></p>
</div>
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img width="180px" height="200px" src="<%=imgPath %>${goods.pic }"></a>
</div>
</c:if>
<c:if test="${i.count ==3 }">
<div class="popu cont_border_top3 popu_shadow " style="text-align: center;">
<div class="popu_bottom">
<h2 class="con_title">游戏</h2>
<h4 class="popu_name">${goods.name }</h4>
<p class="popu_desc"><a href="">${goods.mark }</a></p>
<p class="popu_price"><a href="">${goods.price }米币</a></p>
</div>
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img width="200px" height="150px" src="<%=imgPath %>${goods.pic }"></a>
</div>
</c:if>
<c:if test="${i.count ==4 }">
<div class="popu popu_border_top4 popu_shadow " style="text-align: center;">
<div class="popu_bottom">
<h2 class="con_title">应用</h2>
<h4 class="popu_name">${goods.name }</h4>
<p class="popu_desc"><a href="">${goods.mark }</a></p>
<p class="popu_price"><a href="">${goods.price }米币</a></p>
</div>
<a href="indexServlet?fs=findGoodsDetail&gid=${goods.gid }" target="_blank"><img width="200px" height="150px" src="<%=imgPath %>${goods.pic }"></a>
</div>
</c:if>
</c:forEach> --%>
<!-- 原始网页 -->
<div class="popu cont_border_top1 popu_unleft popu_shadow">
<div class="popu_bottom">
<h2 class="con_title">图书</h2>
<h4 class="popu_name">哈利·波特与被诅咒的孩子</h4>
<p class="popu_desc"><a href="">“哈利·波特”第八个故事中文版震撼来袭!特别彩排版剧本! </a></p>
<p class="popu_price"><a href="">29.37元</a></p>
</div>
<a href=""><img src="img/cont_01.jpg"></a>
</div>
<div class="popu cont_border_top2 popu_shadow ">
<div class="popu_bottom">
<h2 class="con_title">MIUI 主题</h2>
<h4 class="popu_name">包宝宝养成记</h4>
<p class="popu_desc"><a href="">包宝宝定制主题Q萌上线!快来领取萌萌包宝宝吧!</a></p>
<p class="popu_price"><a href="">4.2米币</a></p>
</div>
<a href=""><img src="img/cont_02.jpg"></a>
</div>
<div class="popu cont_border_top3 popu_shadow ">
<div class="popu_bottom">
<h2 class="con_title">游戏</h2>
<h4 class="popu_name">小米超神</h4>
<p class="popu_desc"><a href="">实力派!一起团!</a></p>
<p class="popu_price"><a href=""></a></p>
</div>
<a href=""><img src="img/cont_03.jpg"></a>
</div>
<div class="popu popu_border_top4 popu_shadow ">
<div class="popu_bottom">
<h2 class="con_title">应用</h2>
<h4 class="popu_name">2017金米奖</h4>
<p class="popu_desc"><a href="">最优秀的应用和游戏</a></p>
<p class="popu_price"><a href=""></a></p>
</div>
<a href=""><img src="img/cont_04.jpg"></a>
</div>
</div>
</div>
</div>
<div class="video">
<div class="popular_background">
<div class="popular_box_top">
<div class="popular_box_top_al">视频</div>
</div>
<div class="popu_box">
<div class="vid popu_unleft popu_shadow">
<div class="video_top">
<a href=""><video class="this_vid" src="img/snowPerson.mp4" controls loop poster="img/video_01.jpg"></video></a>
</div>
<div class="video_bottom">
<h3 class="vid_title"><a href="">小米8,一部与众不同的手机</a></h3>
<p class="vid_desc">透明探索版,将科技与美学完美结合</p>
</div>
</div>
<div class="vid popu_shadow">
<div class="video_top">
<a href=""><video class="this_vid" src="img/snowPerson.mp4" controls loop poster="img/video_02.jpg"></video></a>
</div>
<div class="video_bottom">
<h3 class="vid_title"><a href="">小米MIX 2S,一面科技 一面艺术</a></h3>
<p class="vid_desc">艺术品般陶瓷机身,惊艳、璀璨</p>
</div>
</div>
<div class="vid popu_shadow">
<div class="video_top">
<a href=""><video class="this_vid" src="img/snowPerson.mp4" controls loop poster="img/video_03.jpg"></video></a>
</div>
<div class="video_bottom">
<h3 class="vid_title"><a href="">天生丽质的小米6X</a></h3>
<p class="vid_desc">让你一见倾心</p>
</div>
</div>
<div class="vid popu_shadow">
<div class="video_top">
<a href=""><video class="this_vid" src="img/snowPerson.mp4" controls loop poster="img/video_01.jpg"></video></a>
</div>
<div class="video_bottom">
<h3 class="vid_title"><a href="">生活中无所不在的小爱同学</a></h3>
<p class="vid_desc">透明探索版,将科技与美学完美结合</p>
</div>
</div>
</div>
</div>
</div>
<!-- 底部的包含 -->
<jsp:include page="footer.jsp"></jsp:include>
<script>
var abc = document.getElementsByClassName("script_capa_box_top_ar");
console.log("abc:"+abc);
console.log("abc[0]"+abc[0]);
var box = document.getElementsByClassName("scrip_capa_box");
console.log("box:"+box);
console.log("box[0]:"+box[0]);
for(var i = 0; i<abc.length;i++){
abc[i].index=i;
abc[i].onmouseover=function(){
for(var j = 0 ;j<abc.length;j++){
box[j].className="capa_box scrip_capa_box";
}
box[this.index].className="capa_box scrip_capa_box scrip_capa_box_on"
console.log("this.index:"+this.index);
}
}
var n = 0;
/*setInterval(function () {
n++;
if(n > $(".scroll ul li").length){
n=0;
}
$(".scroll ul li").css("opacity","0").eq(n).css("opacity","1")
},100)*/
var t = setInterval(fun,1000);
function fun() {
n++;
if(n > $(".scroll>ul>li").length-1){
n = 0;
}
$(".scroll>ul>li").css("opacity","0").eq(n).css("opacity","1")
$(".scroll_dot span").eq(n).addClass("scroll_dot_span").siblings().removeClass("scroll_dot_span");
}
$(".scroll_arrows .left").click(function() {
n -= 2;
if(n <-1){
n=4;
}
fun()
} );
$(".scroll_arrows .right").click(function() {
fun()
});
$(".scroll_dot span").click(function () {
console.log($(this).index());
n=$(this).index()-1;
$(this).siblings().removeClass("scroll_dot_span").end().addClass("scroll_dot_span");
fun()
}); $(".scroll").hover(function () {
clearInterval(t);
},
function () {
t = setInterval(fun,1000);
});
</script>
</body>
</html>
2.1servlet对数据的控制及其响应的结果
//在主页面中实现商品的连接的跳转,跳转到商品的详情的页面
public String findDetailByGid(HttpServletRequest request,HttpServletResponse response){
System.out.println("主页面实现跳转后实现页面的详情的内容");
//1.从前端页面中获取数据,获取的商品的id信息用来作为商品的查询的回显信息的条件
String gid = request.getParameter("gid");
//2.调用service层,处理业务逻辑
Goods goods = gs.findGoodsByGid(gid);
System.out.println(goods+"****");
//3.对返回的结果做非空的校验,跳转到商品的详细的页面,剩下的商品的信息就是在页面中做处理
if (goods != null){
//4.将商品的信息存入到域对象中,便于商品的在前端的页面的显示
request.setAttribute("goods",goods);
return "./detail.jsp";
}
return null;
}
//登录成功后首先从数据库中动态的获取数据,然后再通过循环输出到页面上
public String findAllInfo(HttpServletRequest request,HttpServletResponse response){
System.out.println("欢迎登录到查询所有的展示的信息的页面");
try {
//查询商品分类 查询10条商品信息较高的商品
List<Category> clist = cs.findCategorys(10);
//查询5条小米明星商品 4表示基本状态为4的
List<Goods> starList = gs.findStarGoods(4,5);
//分别将商品的分类的信息和商品的信息添加中
request.setAttribute("clist",clist);
request.setAttribute("starList",starList);
} catch (Exception e) {
e.printStackTrace();
}
return "./index.jsp";
}
3.加入购物车模块上篇博客已经做了非常好的讲解了,下面不在讲解
4.订单模块
4.1订单的jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
//获取项目名
String path = request.getContextPath();
//获取tomcat 协议+地址+端口号+ 获取项目名
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
//获取tomcat 协议+地址+端口号
String imgPath2 = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/xmsms_goods/";
%>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${goods.name}</title>
<link rel="stylesheet" href="css/index.css">
<script src="js/jquery.1.11.1.min.js"></script>
<script>
/*使用ajax将商品添加到购物车中去*/
function add() {
var user = "${sessionScope.user}";
if (user.trim()==""){
alert("域对象中没有值")
location.href="<%=basePath %>login.jsp";
}else {
//用户成功,将用户的信息添加到购物车中去
$.post("<%=basePath %>trolleyServlet",{method:"addTrolley",gid:"${goods.gid}"},function (data) {
if (data=="2"){
//将购物车中传入的数据加一
var num = $("#trolleyCount").text();
$("#trolleyCount").text(Number(num)+1);
}
});
}
}
</script>
</head>
<body>
<!-- 动态包含头部信息 -->
<jsp:include page="header.jsp"></jsp:include>
<div class="logo">
<div class="logo_left">
<div>
<a href="index.html" title="小米官网"><img class="xiaomi" src="img/logo.jpg"></a>
</div>
</div>
<ul class="logo_center orangeGL">
<a href="">小米手机</a>
<a href="">红米</a>
<a href="">笔记本</a>
<a href="">电视</a>
<a href="">盒子</a>
<a href="">新品</a>
<a href="">路由器</a>
<a href="">智能硬件</a>
<a href="">服务</a>
<a href="">社区</a>
</ul>
<formv class="logo_right">
<div class="logo_input"><input type="text">
<div class="logo_input_div">
</div>
</div>
<a class="logo_right_a"><img src="img/find.jpg"></a>
</formv>
</div>
<div class="plus5_no1">
<h2 class="plus5_no1_float">${goods.name}</h2>
<a href="javascript:;" class="plus5_no1_float_rigth">用户评价概述</a>
<span class="plus5_no1_float_rigth">|</span>
<a href="javascript:;" class="plus5_no1_float_rigth">F码通道</a>
<span class="plus5_no1_float_rigth">|</span>
<a href="javascript:;" class="plus5_no1_float_rigth">概述</a>
</div>
<c:if test="${sessionScope.user == null}">
<div class="plus5_no2 ">
<div class="plus5_no2_in">
<a class="plus5_no2_in_a"> 为方便您购买,请提前登录 </a>
<a class="plus5_no2_in_a orange"style="color: pink;" href="login.jsp">立即登录</a>
<a id="plus5_no2_in" class="plus5_no2_in_a" href="javascript:;">x</a>
</div>
</div>
</c:if>
<div class="plus5_no3">
<div class="plus5_no3_img">
<%--添加图片的信息并存入到相对应的位置--%>
<img src="<%=imgPath2 %>${goods.pic}" style="display: block;width: 500px;height: 500px" alt="">
</div>
<div class="plus5_no3_right">
<h1>${goods.name}</h1>
<p class="plus5_no3_right_p2"><span class="plus5_no3_right_span2">「64GB立减200元」</span>${goods.description}</p>
<p class="plus5_no3_right_p3">${goods.price}<span class="plus5_no3_right_span3">${goods.price+100}</span></p>
<div class="plus5_no3_right_div4">
<div class="plus5_no3_right_div4_in">
<p class="plus5_no3_right_p4">赠品</p><span>生活美满三件套</span>
</div>
<div class="plus5_no3_right_div4_in">
<p class="plus5_no3_right_p4">赠品</p><span>人生意外保险三年服务</span>
</div>
</div>
<div class="plus5_no3_right_div5">
<p >北京 北京市 东城区 永定门外街道 <span class="plus5_no3_right_div5_span"><a class="plus5_no3_right_div5_span" href="">修改</a><br>有现货</span></p>
</div>
<div class="plus5_no3_right_div6">选择版本</div>
<div class="plus5_no3_right_div7">
<li class="plus5_no3_right_div7_in plus5_no3_right_div7_in_hover">
<span class="plus5_no3_right_div7_span0 ">3GB+32GB</span>
<span class="plus5_no3_right_div7_span " >999元</span>
</li>
<li class="plus5_no3_right_div7_in plus5_no3_float">
<span class="plus5_no3_right_div7_span0 ">4GB+64GB</span>
<span class="plus5_no3_right_div7_span " >1299元</span>
</li>
</div>
<div class="plus5_no3_right_div6">选择颜色</div>
<div class="plus5_no3_right_div9">
<li class="plus5_no3_right_div7_in plus5_no3_right_div7_in_hover "><img src="img/plus5_phone_01.png" alt=""><span>金色</span></li>
<li class="plus5_no3_right_div7_in plus5_no3_float"><img src="img/plus5_phone_02.png" alt=""><span>黑色</span></li>
</div>
<div class="plus5_no3_right_div10">
<p class="plus5_no3_right_div10_p1">${goods.name} <span class="plus5_no3_right_div10_span0">4GB+64GB</span> <span class="plus5_no3_right_div10_span1"></span><span class="plus5_no3_right_div10_span2">金色</span></p><span class="plus5_no3_right_span10">999元</span>
<p class="plus5_no3_right_div10_p2">总计:${goods.price}元</p>
</div>
<a onclick="add()"><div class="plus5_no3_right_div11">加入购物车</div></a>
<div class="plus5_no3_right_div12">
<div class="plus5_no3_right_div12_y">√</div>
<div class="plus5_no3_right_div12_z">七天无理由退货</div>
<div class="plus5_no3_right_div12_y">√</div>
<div class="plus5_no3_right_div12_z">15天质量问题换货</div>
<div class="plus5_no3_right_div12_y">√</div>
<div class="plus5_no3_right_div12_z">360天保障</div>
</div>
<a href="javascript:void (0);"></a>
</div>
</div>
<div class="fixed">
<div class="fixed_in">
<a class="fixed_a" href=""><img src="img/fixed_01.png" alt="" class="fixed_img"></a>
<p class="fixed_p">个人中心</p>
</div>
<div class="fixed_in">
<a class="fixed_a" href=""><img src="img/fixed_02.png" alt="" class="fixed_img"></a>
<!--<a class="fixed_a" href=""><img src="img/fixed_o_02.png" alt="" class="fixed_img"></a>-->
<p class="fixed_p">联系客服</p>
</div>
<div class="fixed_in">
<a class="fixed_a" href=""><img src="img/fixed_03.png" alt="" class="fixed_img"></a>
<p class="fixed_p">购物车</p>
</div>
<div class="fixed_in fi_bottmo">
<a class="fixed_a" href=""><img src="img/fixed_04.png" alt="" class="fixed_img"></a>
<p class="fixed_p">回到顶部</p>
</div>
</div>
<!-- 动态包含尾部 -->
<jsp:include page="footer.jsp"></jsp:include>
<script>
var plus5_no2_in = document.getElementById("plus5_no2_in");
var plus5_no2 = document.getElementsByClassName("plus5_no2")[0];
$(".plus5_no3_right_div9 .plus5_no3_right_div7_in").click(function () {
console.log($(this).children().eq(1).html());
$(".plus5_no3_right_div10_span2").html($(this).children().eq(1).html());
$(".plus5_no3_img img").css("display","none").eq($(this).index()).css("display", "block");
$(this).siblings().removeClass("plus5_no3_right_div7_in_hover").end().addClass("plus5_no3_right_div7_in_hover");
})
$(".plus5_no3_right_div7 .plus5_no3_right_div7_in").click(function () {
console.log($(this).children().eq(1).html());
$(".plus5_no3_right_div10_span0").html($(this).children().html());
$(".plus5_no3_right_span10").html($(this).children().eq(1).html());
var value = "总计:"+$(this).children().eq(1).html()
$(".plus5_no3_right_div10_p2").html(value);
$(this).siblings().removeClass("plus5_no3_right_div7_in_hover").end().addClass("plus5_no3_right_div7_in_hover");
})
</script>
</body>
</html>
4.2其相对应的servlet控制层对数据的判断的功能,故先添加订单,然后再从相对于的数据中取出数据,传到域对象中去,完成业务需要后,在购物车表中将对应的信息改为支付过后的状态
package cn.ujiuye.web.servlet;
import cn.ujiuye.domain.Orders;
import cn.ujiuye.domain.User;
import cn.ujiuye.service.OrdersService;
import cn.ujiuye.service.impl.OrdersServiceImpl;
import cn.ujiuye.utils.BaseServlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author liugang
* @date 2019/9/28
* 订单商品的sevlet对象
*/
@WebServlet("/ordersServlet")
public class OrdersServlet extends BaseServlet {
OrdersService service = new OrdersServiceImpl();
//demo例子
public String demo(HttpServletRequest request,HttpServletResponse response){
System.out.println("登录成功后先查询然后再实现页面的跳转");
return null;
}
//订单成功后将state的状态变成1
public String changeState(HttpServletRequest request,HttpServletResponse response) throws IOException {
System.out.println("登录成功后订单状态的跳转的连接");
//1.从前台获取数据
String orders_number = request.getParameter("orders_number");
int state = Integer.parseInt(request.getParameter("state"));
//2.修改订单状态
service.changeState(orders_number,state);
//3.重定向到的登录界面
response.sendRedirect(request.getContextPath());
return null;
}
//当用户添加付款功能的时候,会自动往订单表中插入我们想要的数据
public String addOrders(HttpServletRequest request,HttpServletResponse response){
//1.从前台获取我们输入的信息 总金额 数据量
double sumPrice = Double.parseDouble(request.getParameter("sumPrice"));
int count = Integer.parseInt(request.getParameter("count"));
//2.从域对象中获取session的值,从而判断用户的信息
User user = (User) request.getSession().getAttribute("user");
//3.处理业务逻辑
service.addOrders(sumPrice,count,user.getUid());
//4.进入到付款页面 首先获取到订单信息
Orders orders = service.findOrdersByUid(user.getUid());
System.out.println(orders+"*******");
//5.将信息存入到域对象中,并转发到相对应的页面中去
request.setAttribute("orders",orders);
return "./pay/index.jsp";
}
}
4.3表示对业务逻辑的控制
package cn.ujiuye.service.impl;
import cn.ujiuye.dao.OrdersDao;
import cn.ujiuye.dao.TrolleyDao;
import cn.ujiuye.dao.impl.OrdersDaoImpl;
import cn.ujiuye.dao.impl.TrolleyDaoImpl;
import cn.ujiuye.domain.Orders;
import cn.ujiuye.service.OrdersService;
import cn.ujiuye.utils.UUIDUtils;
/**
* @author liugang
* @date 2019/9/28
* 订单的业务逻辑的实现类,实现了对接口的实现
*/
public class OrdersServiceImpl implements OrdersService {
OrdersDao dao = new OrdersDaoImpl();
TrolleyDao td = new TrolleyDaoImpl();
/**
* 订单信息的生成,注意到各个字段的生成规则
* @param sumPrice
* @param count
* @param uid
*/
@Override
public void addOrders(double sumPrice, int count, int uid) {
//订单号作为主键,是利用UUID生成的
String orders_number = UUIDUtils.getId();
dao.addOrders(sumPrice,count,uid,orders_number);
//在购物车中失联的信息,此时需要添加订单号
td.updateTrolleys(uid,orders_number);
}
/**
* 根据用户的id来查询所有的订单的信息
* @param uid
* @return
*/
@Override
public Orders findOrdersByUid(int uid) {
try {
return dao.findOrdersByUid(uid);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public void changeState(String orders_number, int state) {
dao.changeState(orders_number,state);
}
}
4.3.对数据的持久化的业务逻辑的交互
package cn.ujiuye.dao.impl;
import cn.ujiuye.dao.OrdersDao;
import cn.ujiuye.domain.Orders;
import cn.ujiuye.utils.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @author liugang
* @date 2019/9/28
* 持久化对象
*/
public class OrdersDaoImpl implements OrdersDao {
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 根据的各个信息,在数据库中生成其相对应的信息
* @param sumPrice
* @param count
* @param uid
* @param orders_number
*/
@Override
public void addOrders(double sumPrice, int count, int uid, String orders_number) {
String sql = " insert into orders (orders_number,uid,sum_Price,count_number) values(?,?,?,?) ";
template.update(sql,orders_number,uid,sumPrice,count);
}
/**
* 根据用户的id信息订单信息来判断其订单的信息
* @param uid
* @return
*/
@Override
public Orders findOrdersByUid(int uid) {
//1.定义sql
String sql = "select * from orders where uid = ? and state = 0";
return template.queryForObject(sql,new BeanPropertyRowMapper<Orders>(Orders.class),uid);
}
/**
* 修改订单表中的商品的状态
* @param orders_number
* @param state
*/
@Override
public void changeState(String orders_number, int state) {
//1.定义sql
String sql = "update orders set state=? where orders_number = ?";
template.update(sql,state,orders_number);
}
}
5.支付功能
5.1相关的接口的配置
package cn.alipy.config;
import java.io.FileWriter;
import java.io.IOException;
/* *
*类名:AlipayConfig
*功能:基础配置类
*详细:设置帐户有关信息及返回路径
*修改日期:2019-09-28
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "2016101400683987";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCpaqtgGuNMYAPAOHa5chPZR5aJDb49AsErygKbISFwc/JahHJNxAnWqPfudlSHfFz2v6U3C6lClpAobpJ+FJ9KPtqLyieH2BbhoptGDvBPcC1UBovZ75/Oin5EZMVeJyPCUO/K4MysQXujOgG6WissnQ46EunrLlqaviE8sl4CpTjzL9mgnDktxjUXTLHUlCQCDwDuQ5vLWOdg8Di2mCqirABCw8Fal/bslKToGTAVYOS3qnIkd+IrzhOr5f/d3rYIqnZEo73Cq20HrWZMVDg2agb/HWnZq4oYtP+6PUHHaLxEVxNw/G07g5BxKudWAVF7GWpU6mxjHpQPmO1rG8M9AgMBAAECggEAagn2EkVCF7/RGTM+PHyGp+0C7+3GMPHUbtAWKXrnLzejbbyQvtQBRHamGH/AEL1qgpcZlgaafq82s9fhoUDPIu2MZQq3C3PZfokEnykiiNYxyPH//vzZDbHprm1Ui8X7v9hg/p8N/JNQC652/mkJtPbovLix6R4uX8S5kQAjj4tNzkJrR9N4qfYFWMX8bY3ccde+TJb1A7KxZjsRS6oj+XqP8X8xwbHh1u0PiFA7mgQklspRpRXaSpMt7TYx8fH6OGxsUn9uSaD0R8H16us32hLdnZ06F4wEMCpBf4pmt4WlRBtGxxjsLoF5Y7vVEM8JCHEL9e6GPKNHZNKKk8bZAQKBgQDZ4gg0i0UHD8MtDJh7hfeR79P5bdEbmgN2RX5ixZ2V0JEclJjl7WJ2E+FNrwf/qCA/16KPQHzg+6PR0ho+C0gOQhc8HoKJmV//zYwrtICe0BbLuJVM1NMU3gXZYcLd8xQjj8veuysJ3r0u4KkTq92JjfES2YZpyjO2jiczEnYfLQKBgQDHDg7Yt/wzdNFiKtYHtAYUG4pv5ZD4mYhvbcvOj2AVu/i7A7j0IoVKElkVItnlTDo8tZmLknpfOQSVk1+SJD6O8nG/HGU/yaO13cBJEP3x4xNNWJZk7woP2gKxJ/MmIf1LYe+3NEjXuHSNN83vceWCuySR2lYHkf48lzmp7ks+UQKBgQCDeUsuOaOrgS1q76DLWKltHGSyrDt0Bll0cray70AJ+NK3hktE4xt42MIpWCbhdBgRrhLfkjBIqk/N+pPvQGt4fxT6KAbo9O3is6uTa9X4/uPihj1BIWNFwjuRUtZ9i4JpewmwGwz7ZbaOpO4heqGxsT74+t2K1IKj899fiBJS+QKBgHLkP1eBYnVE0PILbXwGwZdrig0qAPIslB5UzlUMVlZVJ6yx6lgncK2fR4G2mvQJene+DcEMq8s4etfmtzv/5YfWkibPufUGapK3SpwhzaGHAoYbQrtBaZpaqEEeoO56oduXzKf+6qhwk/1Kn3e8Us+ROvtgfVVjQ84vLx5RJ2bxAoGBANAXhk6bfIlNihUymyu6Td2xezM/EB4LwZxQqIXwd2XSU7V7QIS3bUoUmRf7sPb1Qtv0mdAbEwlk9Dsx9wDy99Jt5sqpJQN9e8KDjqAiDVxR0orNEvwL1TlmSmFDlpkSrkhgomSqu2r+d7GS0UxJ9AsikFs2+biBGkJjU0mIa6tc"; // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqWqrYBrjTGADwDh2uXIT2UeWiQ2+PQLBK8oCmyEhcHPyWoRyTcQJ1qj37nZUh3xc9r+lNwupQpaQKG6SfhSfSj7ai8onh9gW4aKbRg7wT3AtVAaL2e+fzop+RGTFXicjwlDvyuDMrEF7ozoBulorLJ0OOhLp6y5amr4hPLJeAqU48y/ZoJw5LcY1F0yx1JQkAg8A7kOby1jnYPA4tpgqoqwAQsPBWpf27JSk6BkwFWDkt6pyJHfiK84Tq+X/3d62CKp2RKO9wqttB61mTFQ4NmoG/x1p2auKGLT/uj1Bx2i8RFcTcPxtO4OQcSrnVgFRexlqVOpsYx6UD5jtaxvDPQIDAQAB";
public static String notify_url = "http://localhost:8080/XMSMS/pay/notify_url.jsp";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://localhost:8080/XMSMS/pay/return_url.jsp";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
// 支付宝网关
public static String log_path = "C:\\";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* @param sWord 要写入日志里的文本内容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五.总结