本帖最后由 小石姐姐 于 2018-6-21 14:24 编辑
网上商城 学习笔记
准备工作解决一个请求对应一个Servlet导致的Servlet过多的方案: 创建通用的Servlet类,利用反射重写其中的service方法,各个模块的Servelt继承此类,只需按照约定的参数及返回值编写方法即可 [Java] 纯文本查看 复制代码 public class BaseServlet extends HttpServlet{
public void service(HttpServletRequest req,HttpServletResponse resp){
//获取要调用的的方法名称
String methodName = request.getParameter(“method”);
// 获得Class,利用反射执行方法
Class clazz = this.getClass();
Method method = clazz.getMethod(methodName,HttpServletRequest.class,HttpSerlvetResponse.class);
//接收方法的返回值,如果不为null就转发
String path = (String)method.invoke(this,req,resp);
if(path != null){
req.getRequestDispatcher(path).forward(req,resp);
}
}
} 用户模块用户登陆
验证码 通过ajax将请求发送到负责生成验证码的Servlet,产生验证码并存到session中; 登陆校验时首先验证session中的验证码与从前台中获得的验证是否一致,如果不一致,则登陆失败,如果一致再执行后续的代码; 记住用户名 1.前台: [HTML] 纯文本查看 复制代码 <!--用户名文本框-->
<input type="text" class="form-control" id="username" name="username" value="${cookie.username.value }" placeholder="请输入用户名">
<!--记住用户名复选框-->
<input type="checkbox" name="remember" value="true"> 记住用户名
2.后台:如果从前台获得的值为true并且登陆成功时,则将用户名存入到cookie中 [Java] 纯文本查看 复制代码 String remember = request.getParameter("remember");
if("true".equals(remember)){
Cookie cookie = new Cookie("username", existUser.getUsername());
cookie.setPath(request.getContextPath());
cookie.setMaxAge(60*60*24);
response.addCookie(cookie);
} 自动登陆
[HTML] 纯文本查看 复制代码 <!--自动登录复选框-->
<input type="checkbox" name="autoLogin" value="true"> 自动登录
[Java] 纯文本查看 复制代码 //仅需在session中没有用户信息,cookie中存在且正确的情况下才需要在把用户信息存到session中,其他情况直接放行
HttpServletRequest req = (HttpServletRequest) request;//转为HttpServletRequest对象
HttpSession session = req.getSession();//获取session
User existUser = (User) session.getAttribute("existUser");//获取session中的用户信息
if (existUser == null) {//如果用户信息不存在
Cookie[] cookies = req.getCookies();
Cookie c = CookieUtils.getCookie(cookies, "autoLogin");//获取保存登陆信息的cookie
if (c != null) {//如果cookie不为空,也就是登陆信息存在
String username = c.getValue().split("#")[0];//获取保存的用户信息
String password = c.getValue().split("#")[1];
User user = new User();
user.setUsername(username);
user.setPassword(password);
try {
existUser = new UserServiceImpl().login(user);//查询cookie中保存的是否正确
if (existUser != null) {//如果能查到,将该信息保存到session中
session.setAttribute("existUser", existUser);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
chain.doFilter(req, response);//其他条件直接放行
用户注册
异步用户名校验
前台 [JavaScript] 纯文本查看 复制代码 $("#username").bind("blur",function(){
if($(this).val()!=""){
$.ajax({
url:"${pageContext.request.contextPath}/UserServlet",
data:{username:$(this).val(),"method":"checkUsername"},
success:function(data){
if(data!=""){
if(data==0){//如果后台返回的值为0,则表示用户名可用
$("#msgSpan").html("<font class='msg' color='green'>用户名可用</font>");
$("#submit").prop("disabled",false);
}else if(data==1){//如果后台返回的值为1,则表示用户名不可用
$("#msgSpan").html("<font class='msg' color='red'>用户名不可用</font>");
$("#submit").prop("disabled",true);
}
}
}
});
}else{
$("#msgSpan").empty();
}
}); 后台 [Java] 纯文本查看 复制代码 public String checkUsername(HttpServletRequest request,HttpServletResponse response){
String username = request.getParameter("username");
try {
User existUser = new UserServiceImpl().checkUsername(username);
if(existUser == null){
response.getWriter().print(0);
}else{
response.getWriter().print(1);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
发送邮件的实现 [Java] 纯文本查看 复制代码 public static void sendMail(String to, String code){
Properties props = new Properties();
//props.setProperty("smtp", "localhost");
//props.setProperty("pop", "localhost");
Session session = Session.getInstance(props, new Authenticator(){
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("service@store.com", "111");
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("service@store.com"));
message.addRecipient(RecipientType.TO, new InternetAddress(to));
message.setSubject("来自商城的激活邮件");
message.setContent("<h3>请点击激活</h3><h3><a href='http://localhost:8080/store_v2.0/UserServlet?method=active&code="+code+"'>http://localhost:8080/store_v2.0/UserServlet?method=active&code="+code+"</a></h3>","text/html;charset=UTF-8");
Transport.send(message);
} catch (Exception e) {
e.printStackTrace();
}
} 激活账户 点击邮件中的链接,向Servlet发送请求,将数据库中保存激活码的字段置为null;
用户退出 销毁存储在浏览器的cookie 手动将session设置过期 [Java] 纯文本查看 复制代码 public String logOut(HttpServletRequest request, HttpServletResponse response){
Cookie cookie = new Cookie("autoLogin", "");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
request.getSession().invalidate();
return "/index.jsp";
} 邮件 邮件相关概念:
邮箱服务器:如果一台电脑安装了邮箱服务器的软件,这台电脑称为是邮箱服务器.' 电子邮箱:邮箱服务器上的一块空间,通过电子邮箱账号访问这块空间的数据. 收发邮件的协议:
发邮件 SMTP协议:SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。 默认端口号是25 收邮件: POP3协议:POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。是TCP/IP协议族中的一员。默认端口是110 IMAP协议:IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol)
分类模块缓存 当向数据库频繁查询数据,且这些数据不经常变动时,可以将这些数据存储到缓存中;另外,为了更好的用户体验,可以把数据存储到缓存的操作通过Listener放在服务器启动时进行 [Java] 纯文本查看 复制代码 缓存工具类
private static CacheManager cacheManager;//创建缓存管理对象
static{//从配置文件中读取缓存管理对象
cacheManager = CacheManager.create(CacheUtils.class.getClassLoader().getResourceAsStream("ehcache.xml"));
}
public static Object getValue(String cacheName,Object key){
try {
Cache cache = cacheManager.getCache(cacheName);
Element element = cache.get(key);
if(element!=null){
return element.getObjectValue();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void putValue(String cacheName,Object key,Object value){
try {
Cache cache = cacheManager.getCache(cacheName);
Element element = new Element(key,value);
cache.put(element);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void removeCache(String cacheName,Object key) {
Cache cache = cacheManager.getCache(cacheName);
cache.remove(key);
} 热门、最新商品展示 通过is_hot和is_new字段查询List<Product> hotlist 和List<Product> newlist,将这两集合转发到商品展示页面,遍历集合展示 按商品分类分页显示商品信息 通过商品分类id查询PageBean<Product> pageBean,将pageBean对象转发到分类显示页面,遍历pageBean中的List<Product>集合展示
商品模块商品列表 点击栏目后,往ProductServlet中传method,cid参数和当前页(因为需要分页,所以传当前页). 难点: 分页:封装PageBean对象. 了解PageBean对象中属性,封装对象,设置PageBean的参数,然后返回给前台.
当前页数 页面大小 商品总数 总页数:总页数=总数/页面大小 向上取整.注意Double类型向int类型的转换. 装有商品的list集合: 查询商品集合的时候,注意传参,当前页CurrPage,begin开始,和PageSize页面大小;其中begin = (currpage-1)*pageSize;
浏览记录 步骤分析:
获取所有的cookie,的到cookie[] cookies. 查询是否有浏览记录的cookie.判断是否有这样的cookie *如果没有这样的cookie,则创建一个这样的cookie,设置声明周期路径,然后response.add添加回去. *如果有这样的cookie.判断里面是否有此商品的浏览记录,将cookie数组转换成LinkedList集合.便于对里面cookie信息的增删和移动位置 *如果有此商品1,比如原来顺序是 2-1-3,则更改list集合将1删除 然后将1放到第一个. *如果没有此商品的浏览记录,则判断浏览记录长度是否大于指定的浏览记录长度6 *浏览记录大于等于6,删除最后一个,将商品1添加到第一个. *浏览记录小于6,直接将商品1添加到第一个. 遍历list集合,拼接cookie信息的字符串,再截取字符串.此处注意最后一个分隔符需要截取掉. 将cookie写回即可. 返回前台,在前台用java语言根据cookie信息,业务层-dao层查找到商品信息.放到域中,再从jsp页面中调用商品信息即可. [Java] 纯文本查看 复制代码 <-- 商品浏览记录 -->
<%
Cookie[] cookies = request.getCookies();
Cookie cookie = CookieUtils.findCookie(cookies, "history");
if(cookie==null){
out.print("<h3>您还没有浏览记录!</h3>");
return;
}
String value = cookie.getValue();
String[] ids = value.split("-");
ProductService productService = new ProductServiceImpl();
for(String id:ids){
Product product= productService.findByPid(id);
request.setAttribute("p", product);
%>
<li><img src="${pageContext.request.contextPath}/${p.pimage}" /></li>
<%
}
%>
根据商品id查询商品的、将商品对象转发到商品详情页面 购物模块订单模块创建订单和订单项实体
订单Order: [Java] 纯文本查看 复制代码 private Date ordertime;
private Double total;
private Integer state; // 1:未付款 2:已经付款,未发货. 3:已经发货,没有确认收货. 4:已经确认收货,订单结束.
private String address;
private String name;
private String telephone;
private User user;
private List<OrderItem> orderItems = new ArrayList<OrderItem>(); 订单项OrderItem: [Java] 纯文本查看 复制代码 private String itemid;
private Integer count;
private Double subtotal;
private Product product;
private Order order;
生成订单 [Java] 纯文本查看 复制代码 //创建订单
Order order = new Order();
order.setOid(UUIDUtils.getUUID());
order.setOrdertime(new Date());
order.setTotal(cart.getTotalCount());
order.setState(1);
order.setUser(existUser);
//创建订单项
List<OrderItem> orderItems = order.getOrderItems();
Collection<CartItem> cartItems = cart.getMap().values();
for (CartItem cartItem : cartItems) {
OrderItem orderItem = new OrderItem();
orderItem.setItemid(UUIDUtils.getUUID());
orderItem.setCount(cartItem.getCount());
orderItem.setSubtotal(cartItem.getSubTotal());
orderItem.setProduct(cartItem.getProduct());
orderItem.setOrder(order);
orderItems.add(orderItem);//将订单项添加到订单中的集合
}
//调用dao层的save方法将订单保存到数据库
OrderService orderService = (OrderService) BeansFactory.getBean("OrderService");
orderService.save(order); 根据用户id查询订单并分页显示PageBean<Order> pageBean Dao层根据用户id查询,并返回订单集合List<Order> [AppleScript] 纯文本查看 复制代码 public List<Order> findByUid(String uid, int begin, int pageSize) throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from orders where uid = ? order by ordertime desc limit ?,?";
List<Order> list = qr.query(sql, new BeanListHandler<Order>(Order.class), uid, begin, pageSize);//根据用户id查询订单,此时list中并没有product的信息
for (Order order : list) {
sql = "select * from orderitem o,product p where o.oid = ? and o.pid = p.pid";
List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler(), order.getOid());
for (Map<String, Object> map : mapList) { // 遍历List,获取其中的每个Map
Product product = new Product(); // 创建商品对象
BeanUtils.populate(product, map); // 封装商品数据
OrderItem orderItem = new OrderItem(); // 创建订单项
BeanUtils.populate(orderItem, map); // 封装订单项数据
orderItem.setProduct(product); // 将商品信息设置到订单项中
order.getOrderItems().add(orderItem); // 将订单项添加到订单中
}
}
return list;
}
将List<Order>集合封装到pageBean中,转发到页面并遍历 根据订单id查询订单 根据订单id查询,返回订单order [Java] 纯文本查看 复制代码 public Order findByOid(String oid) throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from orders where oid = ?";
Order order = qr.query(sql, new BeanHandler<Order>(Order.class), oid);
sql = "select * from product p,orderitem o where o.oid = ? and o.pid = p.pid";
List<Map<String, Object>> maps = qr.query(sql, new MapListHandler(), oid);
for (Map<String, Object> map : maps) {
Product product = new Product();
BeanUtils.populate(product, map);
OrderItem orderItem = new OrderItem();
BeanUtils.populate(orderItem, map);
orderItem.setProduct(product);
order.getOrderItems().add(orderItem);
}
return order;
}
转发order到页面并取值展示
订单支付
|