一、购物车功能准备工作
1、pinyougou-pojo中创建购物车对象实体类
package com.resultentity;
import java.io.Serializable;
import java.util.List;
import com.pinyougou.pojo.TbOrderItem;
/**
* 购物车实体类
*
* @author wingz
*
*/
public class Cart implements Serializable {
private String sellerId; // 商家id
private String sellerName; // 商家名称
private List<TbOrderItem> orderItems; // 订单项
public String getSellerId() {
return sellerId;
}
public void setSellerId(String sellerId) {
this.sellerId = sellerId;
}
public String getSellerName() {
return sellerName;
}
public void setSellerName(String sellerName) {
this.sellerName = sellerName;
}
public List<TbOrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<TbOrderItem> orderItems) {
this.orderItems = orderItems;
}
}
2、pinyougou-common中编写Cookie工具类
package utils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* Cookie 工具类
*
*/
public final class CookieUtil {
/**
* 得到Cookie的值, 不编码
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (isDecoder) {
retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
* 设置Cookie的值 在指定时间内生效,但不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
* 设置Cookie的值 不设置生效时间,但编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
* 删除Cookie带cookie域名
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
doSetCookie(request, response, cookieName, "", -1, false);
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage
* cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
try {
if (cookieValue == null) {
cookieValue = "";
} else if (isEncode) {
cookieValue = URLEncoder.encode(cookieValue, "utf-8");
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage
* cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
try {
if (cookieValue == null) {
cookieValue = "";
} else {
cookieValue = URLEncoder.encode(cookieValue, encodeString);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到cookie的域名
*/
private static final String getDomainName(HttpServletRequest request) {
String domainName = null;
String serverName = request.getRequestURL().toString();
if (serverName == null || serverName.equals("")) {
domainName = "";
} else {
serverName = serverName.toLowerCase();
serverName = serverName.substring(7);
final int end = serverName.indexOf("/");
serverName = serverName.substring(0, end);
final String[] domains = serverName.split("\\.");
int len = domains.length;
if (len > 3) {
// 127.0.0.1
if (serverName.contains("127.0.0.1")) {
domainName = "localhost";
} else {
// www.xxx.com.cn
domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
}
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = "." + domains[len - 2] + "." + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(":") > 0) {
String[] ary = domainName.split("\\:");
domainName = ary[0];
}
return domainName;
}
}
加入servlet-api依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
3、搭建购物车系统的maven module工程
(1)、搭建interface工程
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.pinyougou</groupId>
<artifactId>pinyougou-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>pinyougou-cart-interface</artifactId>
<dependencies>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
(2)、搭建service工程
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.pinyougou</groupId>
<artifactId>pinyougou-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>pinyougou-cart-service</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-user-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 引入相关jar包 -->
<!-- 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>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 加入spring-data-solr -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>1.5.5.RELEASE</version>
</dependency>
</dependencies>
</project>
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath*:*/*.properties" />
<dubbo:protocol name="dubbo" port="20884"></dubbo:protocol>
<dubbo:application name="pinyougou-cart-service" />
<dubbo:registry address="zookeeper://192.168.25.128:2181" />
<dubbo:annotation package="com.pinyougou.cart.service.impl" />
<dubbo:provider timeout="100000" />
</beans>
applicationContext-tx.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 开启事务控制的注解支持 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>pinyougou-cart-service</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>
</web-app>
(3)、搭建web工程
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.pinyougou</groupId>
<artifactId>pinyougou-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>pinyougou-cart-web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-cart-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-common</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>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 分页插件相关 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- spring-data-solr相关jar -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>1.5.5.RELEASE</version>
</dependency>
<!-- 引入spring-security相关配置 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- 引入springsecurity和cas整合包 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 设置不拦截页面 -->
<http pattern="/register.html" security="none"></http>
<http pattern="/assets/**" security="none"></http>
<http pattern="/css/**" security="none"></http>
<http pattern="/data/**" security="none"></http>
<http pattern="/fonts/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<http pattern="/cart/*.do" security="none"></http>
<!-- entry-point-ref 入口点引用 -->
<http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">
<intercept-url pattern="/**" access="ROLE_USER" />
<csrf disabled="true" />
<!-- custom-filter为过滤器, position 表示将过滤器放在指定的位置上,before表示放在指定位置之前 ,after表示放在指定的位置之后 -->
<custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
<custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />
<custom-filter ref="singleLogoutFilter" before="CAS_FILTER" />
</http>
<!-- CAS入口点 开始 -->
<beans:bean id="casProcessingFilterEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!-- 单点登录服务器登录URL -->
<beans:property name="loginUrl" value="http://cas.pinyougou.com/cas/login" />
<beans:property name="serviceProperties" ref="serviceProperties" />
</beans:bean>
<beans:bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties">
<!--service 配置自身工程的根地址+/login/cas -->
<beans:property name="service" value="http://cart.pinyougou.com/login/cas" />
</beans:bean>
<!-- CAS入口点 结束 -->
<!-- 认证过滤器 开始 -->
<beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<!-- 认证管理器 -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="casAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<!-- 认证提供者 -->
<beans:bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<beans:property name="authenticationUserDetailsService">
<beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:constructor-arg ref="userDetailsService" />
</beans:bean>
</beans:property>
<beans:property name="serviceProperties" ref="serviceProperties" />
<!-- ticketValidator 为票据验证器 -->
<beans:property name="ticketValidator">
<beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<beans:constructor-arg index="0" value="http://cas.pinyougou.com/cas" />
</beans:bean>
</beans:property>
<beans:property name="key" value="an_id_for_this_auth_provider_only" />
</beans:bean>
<!-- 认证类 -->
<beans:bean id="userDetailsService" class="com.pinyougou.user.service.UserDetailServiceImpl" />
<!-- 认证过滤器 结束 -->
<!-- 单点登出 开始 -->
<beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" />
<beans:bean id="requestSingleLogoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="http://cas.pinyougou.com/cas/logout?service=http://www.baidu.com" />
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout/cas" />
</beans:bean>
<!-- 单点登出 结束 -->
</beans:beans>
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:*/*.properties" />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
<property name="features">
<array>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 引用dubbo 服务 -->
<dubbo:application name="pinyougou-cart-web" />
<dubbo:registry address="zookeeper://192.168.25.128:2181" />
<dubbo:annotation package="com.pinyougou.cart.controller" />
<!-- 配置消费者链接服务的超时时间 -->
<dubbo:consumer timeout="400000" />
</beans>
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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>pinyougou-cart-web</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>
<!-- spirngsecurity过滤器链 -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
二、未登录状态实现进入购物车页面展示购物车中数据
1、cart.html
2、cartController.js
//定义控制器
app.controller("cartController", function($scope, cartService) {
/**
* 页面加载展示购物车中数据
*/
$scope.findCartList = function(){
cartService.findCartList().success(function(data){
$scope.cartList = data;
//计算页面需要展示的其他数据
$scope.totalNum = 0; //总数量
$scope.totalFee = 0.00; //总价格
for (var i = 0; i < data.length; i++) {
var orderItemList = data[i].orderItems;
for (var j = 0; j < orderItemList.length; j++) {
$scope.totalNum += orderItemList[j].num;
$scope.totalFee += orderItemList[j].totalFee;
}
}
});
}
});
3、cartService.js
/*用户的service层代码*/
app.service("cartService", function($http){
//查询所有购物车信息
this.findCartList = function(){
return $http.get("./cart/findCartList.do");
}
});
4、CartController.java
package com.pinyougou.cart.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.resultentity.Cart;
import utils.CookieUtil;
/**
* 购物车
*
* @author wingz
*
*/
@RestController
@RequestMapping("/cart")
public class CartController {
@Autowired
private HttpServletRequest request;
@RequestMapping("/findCartList")
public List<Cart> findCrtList() {
// 从cookie中获取购物车信息
String cookieValue = CookieUtil.getCookieValue(request, "cartList", "utf-8");
if (cookieValue == null || cookieValue.trim().equals("")) {
cookieValue = "[]";
}
// 将数据转换为集合
List<Cart> cartList_cookie = JSON.parseArray(cookieValue, Cart.class);
return cartList_cookie;
}
}
三、未登录状态下添加商品到购物车中
1、CartController.java
/**
* 项购物车中添加商品信息
* @param itemId
* @param num
* @return
*/
@RequestMapping("addGoodsToCartList")
public ResultMessage addGoodsToCartList(Long itemId, int num) {
try {
List<Cart> cartList = this.findCartList();
cartList = cartService.addGoodsToCartList(cartList, itemId, num);
//将数据添加到cookie中
CookieUtil.setCookie(request, response, "cartList", JSON.toJSONString(cartList), 3600*24*30, "utf-8");
return new ResultMessage(true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new ResultMessage(false, "添加失败");
}
}
2、CartServiceImpl.java
package com.pinyougou.cart.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.mapper.TbItemMapper;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.pojo.TbOrderItem;
import com.resultentity.Cart;
@Service
public class CartServiceImpl implements CartService {
@Autowired
private TbItemMapper itemMapper;
/**
* 添加数据到购物车中
*/
public List<Cart> addGoodsToCartList(List<Cart> cartList, Long itemId, int num) {
// 判断商品是否存在
TbItem item = itemMapper.selectByPrimaryKey(itemId);
if (item == null) {
throw new RuntimeException("查无此商品!!!");
}
// 判断商家是否在已有购物车中存在
Cart cart = this.findCartFromCartListBySellerId(cartList, item.getSellerId());
if (cart != null) {
// 商家在购物车中有商品
List<TbOrderItem> orderItemList = cart.getOrderItems();
// 判断商家的购物车中是否有要添加的商品
TbOrderItem orderItem = this.findOrderItemFromOrderItemListByItemId(orderItemList, itemId);
if (orderItem != null) {
// 商家的购物车中有要添加的商品
// 修改数量
orderItem.setNum(orderItem.getNum() + num);
// 判断数量是否合法
if (orderItem.getNum() < 0) {
throw new RuntimeException("数量非法");
}
// 判断数量是否为0,如果是,则将商品信息项从购物车项中移除
if (orderItem.getNum() == 0) {
// orderItemList中移除商品
orderItemList.remove(orderItem);
// 移除完毕后还需要判断orderItemList的长度是否为0
if (orderItemList.size() == 0) {
// 如果orderItemList的长度是否为0,那么代表此商家已没有商品,把此商家对象的购物车对象从cartList移除
cartList.remove(cart);
}
}
// 计算总价
orderItem.setTotalFee(new BigDecimal(orderItem.getNum() * orderItem.getPrice().doubleValue()));
} else {
// 如果商品不存在 向 List<TbOrderItem> orderItems中添加一个 TbOrderItem
orderItem = new TbOrderItem();
orderItem = createOrderItem(orderItem, item, num);
orderItemList.add(orderItem);
}
} else {
// 商家在购物车中没有商品
// 创建新的购物车对象
cart = new Cart();
cart.setSellerId(item.getSellerId());
cart.setSellerName(item.getSeller());
// 创建购物项
List<TbOrderItem> orderItems = new ArrayList<TbOrderItem>();
TbOrderItem orderItem = new TbOrderItem();
orderItem = createOrderItem(orderItem, item, num);
orderItems.add(orderItem);
cart.setOrderItems(orderItems);
// 将购物车添加到购物集合中
cartList.add(cart);
}
return cartList;
}
/**
* 创建购物车项
*
* @param orderItem
* @param item
* @param num
* @return
*/
private TbOrderItem createOrderItem(TbOrderItem orderItem, TbItem item, int num) {
if (num < 1) {
throw new RuntimeException("数量非法");
}
orderItem.setGoodsId(item.getGoodsId());
orderItem.setItemId(item.getId());
orderItem.setNum(num);
orderItem.setPicPath(item.getImage());
orderItem.setPrice(item.getPrice());
orderItem.setSellerId(item.getSellerId());
orderItem.setTitle(item.getTitle());
orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue() * orderItem.getNum()));
return orderItem;
}
/**
* 查询购物车中购物项中是否有指定商品信息
*
* @param orderItemList
* @param itemId
* @return
*/
private TbOrderItem findOrderItemFromOrderItemListByItemId(List<TbOrderItem> orderItemList, Long itemId) {
for (TbOrderItem orderItem : orderItemList) {
if (orderItem != null && orderItem.getItemId().equals(itemId)) {
return orderItem;
}
}
return null;
}
private
/**
* 判断购物车中是否有指定商家的商品信息
*
* @param cartList
* @param sellerId
* @return
*/
private Cart findCartFromCartListBySellerId(List<Cart> cartList, String sellerId) {
for (Cart cart : cartList) {
if (cart != null && cart.getSellerId().equals(sellerId)) {
return cart;
}
}
return null;
}
}
四、实现购物车页面数量的动态修改
1、cart.html
2、cartController.js
/**
* 添加数据到购物车中
*/
$scope.addGoodsToCartList = function(itemId, num){
cartService.addGoodsToCartList(itemId, num).success(function(data){
if(data.success){
$scope.findCartList();
}else{
alert(data.message);
}
});
}
3、cartService.js
/**
* 添加商品到购物车中
*/
this.addGoodsToCartList = function(itemId, num){
return $http.get("./cart/addGoodsToCartList.do?itemId=" + itemId + "&num=" + num);
}
五、登陆状态下的向redis中添加购物车数据以及查询购物车数据
1、改造applicaitonContex-security.xml中配置
2、cart.html以及添加index.html
2、改造CartController.java添加的方法
package com.pinyougou.cart.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.pinyougou.cart.service.CartService;
import com.resultentity.Cart;
import com.resultentity.ResultMessage;
import utils.CookieUtil;
/**
* 购物车
*
* @author wingz
*
*/
@RestController
@RequestMapping("/cart")
public class CartController {
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@Reference
private CartService cartService;
@RequestMapping("/findCartList")
public List<Cart> findCartList() {
// 从cookie中获取购物车信息
String cookieValue = CookieUtil.getCookieValue(request, "cartList", "utf-8");
if (cookieValue == null || cookieValue.trim().equals("")) {
cookieValue = "[]";
}
// 将数据转换为集合
List<Cart> cartList_cookie = JSON.parseArray(cookieValue, Cart.class);
//判断用户是否登录
if(!this.getUsername().equals("anonymousUser")) {
//用户已经登录,从redis中获取数据
List<Cart> cartList_redis = cartService.findCartListFromRedis(getUsername());
if(cartList_cookie != null && cartList_cookie.size() > 0) {
//将cookie中的购物车信息取出放入redis中,并清空cookie中的数据
cartList_redis = cartService.mergerCartList(cartList_cookie, cartList_redis);
CookieUtil.deleteCookie(request, response, "cartList");
//将合并后的购物车信息存入redis
cartService.saveCartListsToRedis(cartList_redis, getUsername());
}
return cartList_redis;
}
return cartList_cookie;
}
/**
* 获取登录的用户名
* @return
*/
private String getUsername() {
//如果用户登录,则获取的就是用户自己的名字,如果没有登录,则获取到的是一个固定值:anonymousUser
String name = SecurityContextHolder.getContext().getAuthentication().getName();
return name;
}
/**
* 项购物车中添加商品信息
* @param itemId
* @param num
* @return
*/
@RequestMapping("addGoodsToCartList")
public ResultMessage addGoodsToCartList(Long itemId, int num) {
try {
List<Cart> cartList = this.findCartList();
cartList = cartService.addGoodsToCartList(cartList, itemId, num);
//判断当前用户是否登录
if(getUsername().equals("anonymousUser")) {
//用户没有登录,将购物车信息放入cookie中
CookieUtil.setCookie(request, response, "cartList", JSON.toJSONString(cartList), 3600*24*30, "utf-8");
}else {
//用户已经登录,将数据添加到redis中
cartService.saveCartListsToRedis(cartList, getUsername());
}
return new ResultMessage(true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new ResultMessage(false, "添加失败");
}
}
}
3、改造CartServiceImpl.java中添加的方法
package com.pinyougou.cart.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.mapper.TbItemMapper;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.pojo.TbOrderItem;
import com.resultentity.Cart;
@Service
public class CartServiceImpl implements CartService {
@Autowired
private TbItemMapper itemMapper;
/**
* 添加数据到购物车中
*/
public List<Cart> addGoodsToCartList(List<Cart> cartList, Long itemId, int num) {
// 判断商品是否存在
TbItem item = itemMapper.selectByPrimaryKey(itemId);
if (item == null) {
throw new RuntimeException("查无此商品!!!");
}
// 判断商家是否在已有购物车中存在
Cart cart = this.findCartFromCartListBySellerId(cartList, item.getSellerId());
if (cart != null) {
// 商家在购物车中有商品
List<TbOrderItem> orderItemList = cart.getOrderItems();
// 判断商家的购物车中是否有要添加的商品
TbOrderItem orderItem = this.findOrderItemFromOrderItemListByItemId(orderItemList, itemId);
if (orderItem != null) {
// 商家的购物车中有要添加的商品
// 修改数量
orderItem.setNum(orderItem.getNum() + num);
// 判断数量是否合法
if (orderItem.getNum() < 0) {
throw new RuntimeException("数量非法");
}
// 判断数量是否为0,如果是,则将商品信息项从购物车项中移除
if (orderItem.getNum() == 0) {
// orderItemList中移除商品
orderItemList.remove(orderItem);
// 移除完毕后还需要判断orderItemList的长度是否为0
if (orderItemList.size() == 0) {
// 如果orderItemList的长度是否为0,那么代表此商家已没有商品,把此商家对象的购物车对象从cartList移除
cartList.remove(cart);
}
}
// 计算总价
orderItem.setTotalFee(new BigDecimal(orderItem.getNum() * orderItem.getPrice().doubleValue()));
} else {
// 如果商品不存在 向 List<TbOrderItem> orderItems中添加一个 TbOrderItem
orderItem = new TbOrderItem();
orderItem = createOrderItem(orderItem, item, num);
orderItemList.add(orderItem);
}
} else {
// 商家在购物车中没有商品
// 创建新的购物车对象
cart = new Cart();
cart.setSellerId(item.getSellerId());
cart.setSellerName(item.getSeller());
// 创建购物项
List<TbOrderItem> orderItems = new ArrayList<TbOrderItem>();
TbOrderItem orderItem = new TbOrderItem();
orderItem = createOrderItem(orderItem, item, num);
orderItems.add(orderItem);
cart.setOrderItems(orderItems);
// 将购物车添加到购物集合中
cartList.add(cart);
}
return cartList;
}
/**
* 创建购物车项
*
* @param orderItem
* @param item
* @param num
* @return
*/
private TbOrderItem createOrderItem(TbOrderItem orderItem, TbItem item, int num) {
if (num < 1) {
throw new RuntimeException("数量非法");
}
orderItem.setGoodsId(item.getGoodsId());
orderItem.setItemId(item.getId());
orderItem.setNum(num);
orderItem.setPicPath(item.getImage());
orderItem.setPrice(item.getPrice());
orderItem.setSellerId(item.getSellerId());
orderItem.setTitle(item.getTitle());
orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue() * orderItem.getNum()));
return orderItem;
}
/**
* 查询购物车中购物项中是否有指定商品信息
*
* @param orderItemList
* @param itemId
* @return
*/
private TbOrderItem findOrderItemFromOrderItemListByItemId(List<TbOrderItem> orderItemList, Long itemId) {
for (TbOrderItem orderItem : orderItemList) {
if (orderItem != null && orderItem.getItemId().equals(itemId)) {
return orderItem;
}
}
return null;
}
/**
* 判断购物车中是否有指定商家的商品信息
*
* @param cartList
* @param sellerId
* @return
*/
private Cart findCartFromCartListBySellerId(List<Cart> cartList, String sellerId) {
for (Cart cart : cartList) {
if (cart != null && cart.getSellerId().equals(sellerId)) {
return cart;
}
}
return null;
}
@Autowired
private RedisTemplate redisTemplate;
/**
* 将购物车信息添加到redis中
*/
public void saveCartListsToRedis(List<Cart> cartList, String username) {
redisTemplate.boundHashOps("cartList").put(username, cartList);
}
/**
* 从reids中获取数据
*/
public List<Cart> findCartListFromRedis(String username) {
List<Cart> cartList = (List<Cart>) redisTemplate.boundHashOps("cartList").get(username);
if(cartList == null) {
cartList = new ArrayList<Cart>();
}
return cartList;
}
public List<Cart> mergerCartList(List<Cart> cartList_cookie, List<Cart> cartList_redis) {
for (Cart cart : cartList_cookie) {
List<TbOrderItem> orderItems = cart.getOrderItems();
//判断商家购物车中是否有商品对象
for (TbOrderItem orderItem : orderItems) {
cartList_redis = this.addGoodsToCartList(cartList_redis, orderItem.getItemId(), orderItem.getNum());
}
}
return cartList_redis;
}
}
六、修改生成item.html模板页面以及解决跨域请求ajax的问题
1、修改item.ftl模板页面
2、itemController.js
3、CartController.java
/**
* 项购物车中添加商品信息
*
* @param itemId
* @param num
* @return
*/
@RequestMapping("addGoodsToCartList")
//@CrossOrigin(origins = "*")
//该注解是springmvc提供的,用于解决跨域请求的问题,等同于一下设置reponse的代码,origins设置允许访问的域名,*代表所有域名都可以访问
public ResultMessage addGoodsToCartList(Long itemId, int num) {
// 解决ajax跨域cookie共享的问题
// Access-Control-Allow-Origin是HTML5中定义的一种解决资源跨域的策略,value是允许访问的资源url
// 他是通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。
response.setHeader("Access-Control-Allow-Origin", "http://item.pinyougou.com");
response.setHeader("Access-Control-Allow-Credentials", "true");
try {
List<Cart> cartList = this.findCartList();
cartList = cartService.addGoodsToCartList(cartList, itemId, num);
// 判断当前用户是否登录
if (getUsername().equals("anonymousUser")) {
// 用户没有登录,将购物车信息放入cookie中
CookieUtil.setCookie(request, response, "cartList", JSON.toJSONString(cartList), 3600 * 24 * 30,
"utf-8");
} else {
// 用户已经登录,将数据添加到redis中
cartService.saveCartListsToRedis(cartList, getUsername());
}
return new ResultMessage(true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new ResultMessage(false, "添加失败");
}
}