淘淘商城第十二天


 

1   昨天内容复习

1、在单点登录系统中增加注册和登录的功能

2、登录系统功能判断是否有回调url。

3、Taotao-Protal中添加拦截器。

4、购物车的实现

a)        添加商品商品列表写入cookie中。

b)       展示购物车列表,从cookie中取商品列表

c)        修改购物车的商品数量

d)       删除购物车商品。

 

2   今天内容

1、订单系统的实现(独立的系统)

2、Taotao-portal调用订单系统服务创建订单。

 

3   订单系统的实现

3.1  系统架构

 

3.2  订单系统包含的功能

1、下单功能

2、查看订单列表

3、根据订单号查看订单详情。

 

下单功能一定要使用关系型数据库表,保证数据的一致性。

 

3.3  订单系统服务说明

 

3.4  创建订单系统

3.5  框架整合

Mybatis

Spring

Springmvc

Jedis

可以参考taotao-rest工程整合

 

3.5.1   Ssm整合

3.5.2   Pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

     <modelVersion>4.0.0</modelVersion>

     <parent>

          <groupId>com.taotao</groupId>

          <artifactId>taotao-parent</artifactId>

          <version>0.0.1-SNAPSHOT</version>

     </parent>

     <groupId>com.taotao</groupId>

     <artifactId>taotao-order</artifactId>

     <version>0.0.1-SNAPSHOT</version>

     <packaging>war</packaging>

     <dependencies>

          <dependency>

               <groupId>com.taotao</groupId>

               <artifactId>taotao-manager-mapper</artifactId>

               <version>0.0.1-SNAPSHOT</version>

          </dependency>

          <!-- Spring -->

          <dependency>

               <groupId>org.springframework</groupId>

               <artifactId>spring-context</artifactId>

          </dependency>

          <dependency>

               <groupId>org.springframework</groupId>

               <artifactId>spring-beans</artifactId>

          </dependency>

          <dependency>

               <groupId>org.springframework</groupId>

               <artifactId>spring-webmvc</artifactId>

          </dependency>

          <dependency>

               <groupId>org.springframework</groupId>

               <artifactId>spring-jdbc</artifactId>

          </dependency>

          <dependency>

               <groupId>org.springframework</groupId>

               <artifactId>spring-aspects</artifactId>

          </dependency>

          <dependency>

               <groupId>javax.servlet</groupId>

               <artifactId>servlet-api</artifactId>

               <scope>provided</scope>

          </dependency>

          <dependency>

               <groupId>javax.servlet</groupId>

               <artifactId>jsp-api</artifactId>

               <scope>provided</scope>

          </dependency>

          <!-- Redis客户端 -->

          <dependency>

               <groupId>redis.clients</groupId>

               <artifactId>jedis</artifactId>

          </dependency>

     </dependencies>

     <build>

          <!-- 配置插件 -->

          <plugins>

               <plugin>

                    <groupId>org.apache.tomcat.maven</groupId>

                    <artifactId>tomcat7-maven-plugin</artifactId>

                    <configuration>

                         <port>8085</port>

                         <path>/</path>

                    </configuration>

               </plugin>

          </plugins>

     </build>

</project>

 

3.5.3   Web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

     id="taotao" version="2.5">

     <display-name>taotao-order</display-name>

     <welcome-file-list>

          <welcome-file>index.html</welcome-file>

          <welcome-file>index.htm</welcome-file>

          <welcome-file>index.jsp</welcome-file>

          <welcome-file>default.html</welcome-file>

          <welcome-file>default.htm</welcome-file>

          <welcome-file>default.jsp</welcome-file>

     </welcome-file-list>

     <!-- 加载spring容器 -->

     <context-param>

          <param-name>contextConfigLocation</param-name>

          <param-value>classpath:spring/applicationContext-*.xml</param-value>

     </context-param>

     <listener>

          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

     </listener>

     <!-- 解决post乱码 -->

     <filter>

          <filter-name>CharacterEncodingFilter</filter-name>

          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

          <init-param>

               <param-name>encoding</param-name>

               <param-value>utf-8</param-value>

          </init-param>

     </filter>

     <filter-mapping>

          <filter-name>CharacterEncodingFilter</filter-name>

          <url-pattern>/*</url-pattern>

     </filter-mapping>

     <!-- springmvc的前端控制器 -->

     <servlet>

          <servlet-name>taotao-order</servlet-name>

          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

          <!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocationspringmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->

          <init-param>

               <param-name>contextConfigLocation</param-name>

               <param-value>classpath:spring/springmvc.xml</param-value>

          </init-param>

          <load-on-startup>1</load-on-startup>

     </servlet>

     <servlet-mapping>

          <servlet-name>taotao-order</servlet-name>

          <url-pattern>/order/*</url-pattern>

     </servlet-mapping>

</web-app>

 

3.6  创建订单接口

3.6.1   接口说明

用户使用portal创建订单、android、ios、微信商城提交订单时使用。

请求方法

POST

URL

http://order.taotao.com/order/create

参数说明

 

提交的数据格式:

{

    "payment": 5288,

    "postFee": 0,

    "userId": "3",

    "buyerMessage": null,

    "buyerNick": "zhang123",

    "orderItems": [

        {

            "itemId": "9",

            "num": 1,

            "title": "苹果(Apple)iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机3",

            "price": 5288,

            "totalFee": 5288,

               "picPath": "http://image.taotao.com/images/2015/03/06/2015030610045320609720.jpg"

        }

    ],

    "orderShipping": {

        "receiverName": "张三",

        "receiverPhone": "",

        "receiverMobile": "15800000000",

        "receiverState": "上海",

        "receiverCity": "上海",

        "receiverDistrict": "闵行区",

        "receiverAddress": "三鲁公路3279号 明浦广场 3号楼 205室",

        "receiverZip": "200000"

    }

}

 

示例

 

返回值

{

status200 //200 成功

msg: "OK" // 返回信息消息

data: 100544// 返回订单号

}

 

 

3.6.2   使用到的表

订单表:

订单明细表:

物流表:

3.6.3   Dao层

要对三个表进行操作。都是插入操作。可以使用逆向工程生成的代码。

 

3.6.4   Service层

功能:接收三个参数,

1、对应订单表的pojo。

2、订单明细表对应的商品列表。每个元素是订单明细表对应的pojo

3、物流表对应的pojo

 

订单号的生成:

解决方案一(不能使用):

使用mysql的自增长。

优点:不需要我们自己生成订单号,mysql会自动生成。

缺点:如果订单表数量太大时需要分库分表,此时订单号会重复。如果数据备份后再恢复,订单号会变。

方案二:日期+随机数

采用毫秒+随机数。

缺点:仍然有重复的可能。不建议采用此方案。在没有更好的解决方案之前可以使用。

方案三:使用UUID

优点:不会重复。

缺点:长。可读性查。不建议使用。

 

方案四:可读性好,不能太长。一般订单都是全数字的。可以使用redis的incr命令生成订单号。

优点:可读性好,不会重复

缺点:需要搭建redis服务器。

 

返回值:TaotaoResult

 

@Service

public class OrderServiceImpl implements OrderService {

 

     @Autowired

     private TbOrderMapper orderMapper;

     @Autowired

     private TbOrderItemMapper orderItemMapper;

     @Autowired

     private TbOrderShippingMapper orderShippingMapper;

     @Autowired

     private JedisClient jedisClient;

    

     @Value("${ORDER_GEN_KEY}")

     private String ORDER_GEN_KEY;

     @Value("${ORDER_INIT_ID}")

     private String ORDER_INIT_ID;

     @Value("${ORDER_DETAIL_GEN_KEY}")

     private String ORDER_DETAIL_GEN_KEY;

    

    

     @Override

     public TaotaoResult createOrder(TbOrder order, List<TbOrderItem> itemList, TbOrderShipping orderShipping) {

          //向订单表中插入记录

          //获得订单号

          String string = jedisClient.get(ORDER_GEN_KEY);

          if (StringUtils.isBlank(string)) {

               jedisClient.set(ORDER_GEN_KEY, ORDER_INIT_ID);

          }

          long orderId = jedisClient.incr(ORDER_GEN_KEY);

          //补全pojo的属性

          order.setOrderId(orderId + "");

          //状态:1、未付款,2、已付款,3、未发货,4、已发货,5、交易成功,6、交易关闭

          order.setStatus(1);

          Date date = new Date();

          order.setCreateTime(date);

          order.setUpdateTime(date);

          //0:未评价 1:已评价

          order.setBuyerRate(0);

          //向订单表插入数据

          orderMapper.insert(order);

          //插入订单明细

          for (TbOrderItem tbOrderItem : itemList) {

               //补全订单明细

               //取订单明细id

               long orderDetailId = jedisClient.incr(ORDER_DETAIL_GEN_KEY);

               tbOrderItem.setId(orderDetailId + "");

tbOrderItem.setOrderId(orderId + "");

               //向订单明细插入记录

               orderItemMapper.insert(tbOrderItem);

          }

          //插入物流表

          //补全物流表的属性

          orderShipping.setOrderId(orderId + "");

          orderShipping.setCreated(date);

          orderShipping.setUpdated(date);

          orderShippingMapper.insert(orderShipping);

         

          return TaotaoResult.ok(orderId);

     }

 

}

 

3.6.5   Controller层

接收一个json格式的字符串作为参数。需要使用@RequestBody注解。需要使用一个pojo接收参数。创建一个对应json格式的pojo。

 

package com.taotao.order.pojo;

 

import java.util.List;

 

import com.taotao.pojo.TbOrder;

import com.taotao.pojo.TbOrderItem;

import com.taotao.pojo.TbOrderShipping;

 

public class Order extends TbOrder {

 

     private List<TbOrderItem> orderItems;

     private TbOrderShipping orderShipping;

     public List<TbOrderItem> getOrderItems() {

          return orderItems;

     }

     public void setOrderItems(List<TbOrderItem> orderItems) {

          this.orderItems = orderItems;

     }

     public TbOrderShipping getOrderShipping() {

          return orderShipping;

     }

     public void setOrderShipping(TbOrderShipping orderShipping) {

          this.orderShipping = orderShipping;

     }

    

    

}

 

 

Controller

@Controller

public class OrderController {

 

     @Autowired

     private OrderService orderService;

    

     @RequestMapping("/create")

     @ResponseBody

     public TaotaoResult createOrder(@RequestBody Order order) {

          try {

               TaotaoResult result = orderService.createOrder(order, order.getOrderItems(), order.getOrderShipping());

               returnresult;

          } catch (Exception e) {

               e.printStackTrace();

               return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));

          }

     }

}

 

4   在前台系统生成订单

在taotao-portal系统中添加商品至购物车后,点击提交订单调用taotao-order的服务生成订单。向用户展示订单号。提示创建订单成功。

 

4.1  点击购物车“去结算”按钮

点击“去结算”按钮跳转到订单确认页面。

展示url:/order/order-cart.html

@Controller

@RequestMapping("/order")

public class OrderController {

 

     @RequestMapping("/order-cart")

     public String showOrderCart() {

          return"order-cart";

     }

}

 

4.2  订单确认页面

1、要求用户登录。

2、根据用户id查询用户的收货地址列表。

3、在此页面展示购物车的商品列表。

4、需要计算订单的总金额(包括运费)展示给用户。

 

4.2.1   要求用户登录

修改springmvc.xml拦截所有以:/order/**形式的url

 

4.2.2   根据用户id查询用户的收货地址列表。

在实际的商城中是必须有此功能,需要taotao-rest发布服务,由taotao-portal根据用户查询用户的收货地址列表。

在此,使用静态数据模拟。

 

4.2.3   展示购物车的商品列表

需要从cookie中把购物车商品列表取出,传递给order-cart.jsp。

可以直接使用购物车服务。

@Controller

@RequestMapping("/order")

public class OrderController {

    

     @Autowired

     private CartService cartService;

 

     @RequestMapping("/order-cart")

     public String showOrderCart(HttpServletRequest request, HttpServletResponse response, Model model) {

          //取购物车商品列表

          List<CartItem> list = cartService.getCartItemList(request, response);

          //传递给页面

          model.addAttribute("cartList", list);

         

          return "order-cart";

     }

}

 

4.3  提交订单

点击“提交订单”按钮把用户已经确认的订单信息,提交给后台。提交一个隐藏的表单,其中包含订单基本信息,订单名称以及配送信息。需要使用一个包装的pojo接收表单中的内容。

请求的url:/order/create.html

参数:表单中的内容。使用Order接收表单的内容。

返回值:返回一个jsp页面。

 

4.3.1   Service层

接收Order对象,调用taotao-order提供的服务,提交订单。需要把pojo转换成json数据。调用taotao-order提供的服务返回taotaoResult,包含订单号。

参数:Order

返回值:String(订单号)

@Service

public class OrderServiceImpl implements OrderService {

    

     @Value("${ORDER_BASE_URL}")

     private String ORDER_BASE_URL;

     @Value("${ORDER_CREATE_URL}")

     private String ORDER_CREATE_URL;

    

 

     @Override

     public String createOrder(Order order) {

          //调用taotao-order的服务提交订单。

          String json = HttpClientUtil.doPostJson(ORDER_BASE_URL + ORDER_CREATE_URL, JsonUtils.objectToJson(order));

          //把json转换成taotaoResult

          TaotaoResult taotaoResult = TaotaoResult.format(json);

          if (taotaoResult.getStatus() == 200) {

               Long orderId = (Long) taotaoResult.getData();

               return orderId.toString();

          }

          return "";

     }

 

}

 

4.3.2   Controller层

接收页面提交的表单的内容,调用Service创建订单。返回成功页面。

@Controller

@RequestMapping("/order")

public class OrderController {

    

     @Autowired

     private CartService cartService;

    

     @Autowired

     private OrderService orderService;

 

     @RequestMapping("/order-cart")

     public String showOrderCart(HttpServletRequest request, HttpServletResponse response, Model model) {

          //取购物车商品列表

          List<CartItem> list = cartService.getCartItemList(request, response);

          //传递给页面

          model.addAttribute("cartList", list);

         

          return "order-cart";

     }

    

     @RequestMapping("/create")

     public String createOrder(Order order, Model model) {

          String orderId = orderService.createOrder(order);

          model.addAttribute("orderId", orderId);

          model.addAttribute("payment", order.getPayment());

          model.addAttribute("date", new DateTime().plusDays(3).toString("yyyy-MM-dd"));

          return"success";

     }

    

}

 

 

5   框架梳理

Soa:面向服务的架构

 

Solr集群需要讲。

Mysql的分库分表中间件:MyCat(cobar)提供资料。

 

6   网络拓扑图

 

Nginx:反向代理、负载均衡。

 

7   Nginx

7.1  什么是nginx

Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。开源、免费。

 

7.2  Nginx的应用场景

1、http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。

2、虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。

3、反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

 

 

7.3  Nginx的安装步骤

第一步:把nginx的压缩包上传到服务器

第二步:解压。

第三步:创建一个makefile。

参数设置如下:

./configure \

--prefix=/usr/local/nginx \

--pid-path=/var/run/nginx/nginx.pid \

--lock-path=/var/lock/nginx.lock \

--error-log-path=/var/log/nginx/error.log \

--http-log-path=/var/log/nginx/access.log \

--with-http_gzip_static_module \

--http-client-body-temp-path=/var/temp/nginx/client\

--http-proxy-temp-path=/var/temp/nginx/proxy\

--http-fastcgi-temp-path=/var/temp/nginx/fastcgi\

--http-uwsgi-temp-path=/var/temp/nginx/uwsgi\

--http-scgi-temp-path=/var/temp/nginx/scgi

 

注意:上边将临时文件目录指定为/var/temp/nginx,需要在/var下创建tempnginx目录

第四步:编译make

第五步:安装makeinstall

 

7.4  Nginx实现虚拟机

可以实现在同一台服务运行多个网站,而且网站之间互相不干扰。

 

同一个服务器可能有一个ip,网站需要使用80端口。网站的域名不同。

区分不同的网站有三种方式:

1、ip区分

2、端口区分

3、域名区分

 

7.4.1   Ip区分虚拟主机

需要一台服务器绑定多个ip地址。

方法一:

使用标准的网络配置工具(比如ifconfig和route命令)添加lP别名:

 

当前ip配置情况:

 

在eth0网卡再绑定一个ip:192.168.101.103

 

/sbin/ifconfig eth0:1 192.168.101.103broadcast 192.168.101.255 netmask 255.255.255.0 up

/sbin/route add -host 192.168.101.103 deveth0:1

 

 

方法二:

1、将/etc/sysconfig/network-scripts/ifcfg-eth0文件复制一份,命名为ifcfg-eth0:1

修改其中内容:

DEVICE=eth0:1

IPADDR=192.168.25.103

其他项不用修改

2、重启系统

 

7.4.2   配置nginx基于ip地址的虚拟主机

7.4.2.1        Nginx的配置文件

 

#user  nobody;

worker_processes  1;

 

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

 

#pid        logs/nginx.pid;

 

 

events {

    worker_connections  1024;

}

 

 

http {

    include       mime.types;

    default_type  application/octet-stream;

 

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';

 

    #access_log  logs/access.log  main;

 

    sendfile        on;

    #tcp_nopush     on;

 

    #keepalive_timeout  0;

    keepalive_timeout  65;

 

    #gzip  on;

 

    server { #一个Server就是一个虚拟主机

        listen       80;

        server_name  localhost;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html;

            index  index.html index.htm;

        }

    }

 

}

 

 

7.4.2.2        基于ip的虚拟主机配置

server {

        listen       80;

        server_name  192.168.25.141;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html-141;

            index  index.html index.htm;

        }

 

       

    }

 

    server {

        listen       80;

        server_name  192.168.25.100;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html-100;

            index  index.html index.htm;

        }

 

       

    }

 

Nginx重新加载配置文件。

 

7.4.3   基于端口的虚拟主机

server {

        listen       81;

        server_name  192.168.25.141;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html-81;

            index  index.html index.htm;

        }

 

       

    }

    server {

        listen       82;

        server_name  192.168.25.141;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html-82;

            index  index.html index.htm;

        }

 

       

    }

 

7.4.4   基于域名的虚拟主机

最有用的虚拟主机配置方式。

一个域名只能绑定一个ip地址,一个ip地址可以被多个域名绑定。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


可以修改host文件实现域名访问。

7.4.4.1        设置域名和ip的映射关系

修改window的hosts文件:(C:\Windows\System32\drivers\etc)

 

7.4.4.2        基于域名的虚拟主机配置

server {

        listen       80;

        server_name  www.itheima.com;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html-www;

            index  index.html index.htm;

        }

 

       

    }

 

    server {

        listen       80;

        server_name  hehe.itheima.com;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        location / {

            root   html-hehe;

            index  index.html index.htm;

        }

 

       

    }

修改配置文件后,需要nginx重新加载配置文件。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值