Java Web实战08-Spring、Spring MVC和Hibernate实现收银机系统(XML版本)
2016-07-15 22:14
573 查看
前面参加一个公司的活动,做了一份收银机系统的作业,当时时间紧,花费一天时间用Swing界面做的,比较简单。代码在GitHub:https://github.com/yefengzhichen/twTask。最近正好学习了Spring,以及了解了Html和JSP,于是就将此作业改写成了Spring、Spring MVC、Hibernate、Html和JSP结合的版本。
barcode: 'ITEM000000', name: '可口可乐', unit: '瓶', category: '食品', subCategory: '碳酸饮料', price: 3.00
实现功能:
1、输入商品条形码列表,输出小票详细信息的功能。
输入例子:Item0002,Item0010-10。逗号分隔商品,“-”分隔条形码和数量或者重量。
输出为:
` *<没钱赚商店>购物清单* 名称:apple,数量:10.0kg,单价:13.00(元),小计:130.00(元),优惠:10.00(元) 名称:milk,数量:1.0box,单价:3.50(元),小计:3.50(元)
单品满100减10块商品: 商品:apple,原价:130.0(元),优惠:10.0(元)
总计:123.50(元) 节省:10.00(元)
2、增加打折商品的功能,输入需要打折的商品条形码。
除外,为了练习Hibernate相关,增加了以下功能:
3、注册功能,输入注册信息保存到数据库。
4、登录功能,验证用户是否有效,有效则进入收银机系统。
5、动态添加商品信息功能
主界面展示如下:
web.xml:
root-context.xml,配置了数据库属性,以及C3P0数据源,HIbernate事务管理器,并定义了相应的事务属性。虽然此书的数据库操作都很简单,并没有多个表一起修改的操作,但为了后面扩展,因此定义事务。
数据库连接文件mysql.properties内容:
HIbernate配置文件,和之前的配置一样:
到此,所有的配置已经完成,里面涉及的bean将在下面说明。
商品信息Product类:
利用IDE自动生成相应的Hibernate映射文件:
ProductDao:
对应的实现UserDaoImpl:
对应的ProductDaoImpl:
ProcessServiceImpl:
Usercontroller,定义了用户注册、登录验证相关的处理:
ProcessController,处理需要里面的增加商品信息、增加打折商品、计算价格等处理:
home.jsp,简单的定义两个链接,分别是注册和登录:
RegisterForm,定义注册界面:
profile.jsp,显示注册成功的界面,显示名称和介绍:
start.jsp,收银机系统的主界面,大多数功能处理在此处:
一、需求简介
商店的收银机系统,会根据购买商品和商店的打折活动进行打折。已知商品信息包含:名称,数量单位,单价,类别和条形码(伪)。以下是单个商品对象的结构:barcode: 'ITEM000000', name: '可口可乐', unit: '瓶', category: '食品', subCategory: '碳酸饮料', price: 3.00
实现功能:
1、输入商品条形码列表,输出小票详细信息的功能。
输入例子:Item0002,Item0010-10。逗号分隔商品,“-”分隔条形码和数量或者重量。
输出为:
` *<没钱赚商店>购物清单* 名称:apple,数量:10.0kg,单价:13.00(元),小计:130.00(元),优惠:10.00(元) 名称:milk,数量:1.0box,单价:3.50(元),小计:3.50(元)
单品满100减10块商品: 商品:apple,原价:130.0(元),优惠:10.0(元)
总计:123.50(元) 节省:10.00(元)
2、增加打折商品的功能,输入需要打折的商品条形码。
除外,为了练习Hibernate相关,增加了以下功能:
3、注册功能,输入注册信息保存到数据库。
4、登录功能,验证用户是否有效,有效则进入收银机系统。
5、动态添加商品信息功能
主界面展示如下:
二、实现详细过程
开发环境搭建以及Maven工程构建和本系列之前的一样,在此略过。2.1 JAR包引入
整个项目中,使用的JAR基本都是最新的,直接到Maven Repository上搜索复制的。主要用到的是:Spring 4和Hibernate 5。详细JAR见下面的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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yefeng.spring</groupId> <artifactId>cashapp</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>cashapp Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.1.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-annotations <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency> --> <!-- https://mvnrepository.com/artifact/c3p0/c3p0 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.transaction/jboss-transaction-api_1.1_spec --> <dependency> <groupId>org.jboss.spec.javax.transaction</groupId> <artifactId>jboss-transaction-api_1.1_spec</artifactId> <version>1.0.1.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <!-- https://mvnrepository.com/artifact/jstl/jstl --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-lang/commons-lang --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate.common/hibernate-commons-annotations --> <dependency> <groupId>org.hibernate.common</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>5.0.1.Final</version> </dependency> </dependencies> <build> <finalName>cashapp</finalName> </build> </project>
2.2配置web.xml和各种组件bean
因为将bean配置到两个xml文件root-context.xml、cashapp-context.xml中,web.xml中配置很简单,配置分发器和监听器,以及两个文件的路径以及映射即可。其中,<param-value>的路径默认从根路径webapp下查找,因此当配置在类路径下时,需要加classpath前缀。两个context文件位置放到webapp下或者类路径下都是可以的。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_3_0.xsd" id="schedule-console" version="3.0"> <display-name>Archetype Created Web Application</display-name> <!-- 根配置文件路径,配置除web组件以外的bean,后端的数据层和中间层--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:root-context.xml</param-value> </context-param> <!--加载上面的根配置文件监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置分发器,加载web组件的bean,如控制器、视图解析器 --> <servlet> <servlet-name>cashapp</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/cashapp-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 处理器映射 --> <servlet-mapping> <servlet-name>cashapp</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>cashapp-context.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 静态资源路径配置,配置后,静态资源将不用分发器处理即可获得,此项目中未使用 --> <mvc:resources mapping="/static/**" location="/WEB-INF/static/" /> <!-- mvc配置注解驱动 --> <mvc:annotation-driven/> <!-- 启动自动扫面组件 --> <context:component-scan base-package="com.yefeng.cashapp.web"/> <!-- 视图处理器,自动添加前缀后缀 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
root-context.xml,配置了数据库属性,以及C3P0数据源,HIbernate事务管理器,并定义了相应的事务属性。虽然此书的数据库操作都很简单,并没有多个表一起修改的操作,但为了后面扩展,因此定义事务。
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 启动切面自动代理 --> <aop:aspectj-autoproxy proxy-target-class="true" /> <!-- 读取数据源配置 --> <context:property-placeholder location="classpath:mysql.properties" /> <!-- 自动扫面DAO和Service层的组件 --> <context:component-scan base-package="com.yefeng.cashapp.dao"></context:component-scan> <context:component-scan base-package="com.yefeng.cashapp.service"></context:component-scan> <!-- 数据源bean, --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="initialPoolSize" value="${initPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> </bean> <!--配置Hibernate sessionFactory--> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> <property name="mappingLocations"> <list> <value>classpath:com/yefeng/cashapp/model/User.hbm.xml</value> <value>classpath:com/yefeng/cashapp/model/Product.hbm.xml</value> </list> </property> </bean> <!--配置Hibernate事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!--配置事务切面属性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <!--配置切点 --> <aop:config> <aop:pointcut id="daoPointcut" expression="execution(* com.yefeng.cashapp.dao.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="daoPointcut" /> </aop:config> </beans>
数据库连接文件mysql.properties内容:
user=root password= #com.mysql.cj.jdbc.Driver driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/cashapp?serverTimezone=UTC initPoolSize=5 maxPoolSize=10
HIbernate配置文件,和之前的配置一样:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect </property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property> <property name="hibernate.hbm2ddl.auto">update</property> </session-factory> </hibernate-configuration>
到此,所有的配置已经完成,里面涉及的bean将在下面说明。
2.3 Model层
定义一个User类,对应数据库中user表,保存用户名、密码以及描述信息:package com.yefeng.cashapp.model; public class User { private String name; private String password; private String description; public User() { super(); } public User(String name, String password, String description) { super(); this.name = name; this.password = password; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; }
商品信息Product类:
package com.yefeng.cashapp.model; /** * @author yefengzhichen * 2016年7月10日 */ public class Product { // 名称,数量单位,单价,类别和条形码(伪) private String barcode; private String name; private String unit; private String category; private String subCategory; private Double price; private boolean isDiscount; public Product() { } public Product(String barcode, String name, String unit, String category, String subCategory, Double price) { this.barcode = barcode; this.name = name; this.unit = unit; this.category = category; this.subCategory = subCategory; this.price = price; } public Product(String barcode, String name, String unit, String category, String subCategory, Double price, boolean isDiscount) { super(); this.barcode = barcode; this.name = name; this.unit = unit; this.category = category; this.subCategory = subCategory; this.price = price; this.isDiscount = isDiscount; } public String getBarcode() { return barcode; } public void setBarcode(String barcode) { this.barcode = barcode; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUnit() { return unit; } public void setUnit(String unit) { this.unit = unit; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } public String getSubCategory() { return subCategory; } public void setSubCategory(String subCategory) { this.subCategory = subCategory; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public boolean isDiscount() { return isDiscount; } public void setDiscount(boolean isDiscount) { this.isDiscount = isDiscount; } @Override public String toString() { return "Product [barcode=" + barcode + ", name=" + name + ", unit=" + unit + ", category=" + category + ", subCategory=" + subCategory + ", price=" + price + "]"; } }
利用IDE自动生成相应的Hibernate映射文件:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-7-10 20:28:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.yefeng.cashapp.model.User" table="USER"> <id name="name" type="java.lang.String"> <column name="NAME" /> <generator class="assigned" /> </id> <property name="password" type="java.lang.String"> <column name="PASSWORD" /> </property> <property name="description" type="java.lang.String"> <column name="DESCRIPTION" /> </property> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-7-12 20:25:34 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.yefeng.cashapp.model.Product" table="PRODUCT"> <id name="barcode" type="java.lang.String"> <column name="BARCODE" /> <generator class="assigned" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="unit" type="java.lang.String"> <column name="UNIT" /> </property> <property name="category" type="java.lang.String"> <column name="CATEGORY" /> </property> <property name="subCategory" type="java.lang.String"> <column name="SUBCATEGORY" /> </property> <property name="price" type="java.lang.Double"> <column name="PRICE" /> </property> <property name="isDiscount" type="boolean" access="field"> <column name="ISDISCOUNT" /> </property> </class> </hibernate-mapping>
2.4 DAO层
对以上的两个model类,分别实现对应的DAO层,推荐使用接口编程,因此先定义接口UserDao:package com.yefeng.cashapp.dao; import com.yefeng.cashapp.model.User; public interface UserDao { public void save(User user); public boolean isValid(User user); public void updatePassword(User user); public User get(String name); }
ProductDao:
package com.yefeng.cashapp.dao; import java.util.List; import com.yefeng.cashapp.model.Product; public interface ProductDao { public void save(Product product); public void update(Product product); public Product getByBarcode(String barcode); public boolean contains(Product product); public List<Product> getAll(); public void setDiscount(String barcode); }
对应的实现UserDaoImpl:
package com.yefeng.cashapp.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.yefeng.cashapp.model.User; @Repository(value="userDao") public class UserDaoImpl implements UserDao { @Autowired private SessionFactory sessionFactory; public Session getSession() { return sessionFactory.getCurrentSession(); } @Override public void save(User user) { getSession().save(user); } @Override public boolean isValid(User user) { String name = user.getName(); String hql = "select password from User where name = ?"; List<String> result = getSession().createQuery(hql).setParameter(0, name).getResultList(); String realPassword = result.get(0); if (user.getPassword().equals(realPassword)) { return true; } return false; } @Override public void updatePassword(User user) { String name = user.getName(); String password = user.getPassword(); // String hql = "update User u set u.password = ? where u.name = ?"; // getSession().createQuery(hql).setParameter(0, password).setParameter(1, name); // 推荐下面的命名参数方式 String hql2 = "update User u set u.password=:password where u.name=:name"; Query query2 = getSession().createQuery(hql2); query2.setParameter("password", password); query2.setParameter("name", name); query2.executeUpdate(); } @Override public User get(String name) { String hql = "select u from User u where name = ?"; List<User> result = getSession().createQuery(hql).setParameter(0, name).getResultList(); return result.get(0); } }
对应的ProductDaoImpl:
package com.yefeng.cashapp.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.yefeng.cashapp.model.Product; @Repository(value = "productDao") public class ProductDaoImpl implements ProductDao { @Autowired private SessionFactory sessionFactory; public Session getSession() { return sessionFactory.getCurrentSession(); } @Override public void save(Product product) { if (getSession().contains(product) == false) { getSession().save(product); } } @Override public void update(Product product) { String barcode = product.getBarcode(); String hql = "delete from Product where barcode = ?"; getSession().createQuery(hql).setParameter(0, barcode).executeUpdate(); getSession().save(product); } @Override public Product getByBarcode(String barcode) { String hql = "select p from Product p where barcode = ?"; List<Product> result = getSession().createQuery(hql).setParameter(0, barcode).getResultList(); return result.get(0); } @Override public boolean contains(Product product) { String barcode = product.getBarcode(); String hql = "select p from Product p where barcode = ?"; List<Product> result = getSession().createQuery(hql).setParameter(0, barcode).getResultList(); return result.size() > 0; } @Override public List<Product> getAll() { String hql = "select p from Product p"; List<Product> result = getSession().createQuery(hql).getResultList(); return result; } @Override public void setDiscount(String barcode) { String hql = "update Product p set p.isDiscount=true where p.barcode=:barcode"; Query query = getSession().createQuery(hql); query.setParameter("barcode", barcode); query.executeUpdate(); } }
2.5 Service层
Service层主要实现商品价格清单功能,需要使用DAO进行处理计算,接口ProcessService只有一个方法:package com.yefeng.cashapp.service; public interface ProcessService { public String calculateAll(String inputString); }
ProcessServiceImpl:
package com.yefeng.cashapp.service; import java.text.DecimalFormat; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.yefeng.cashapp.dao.ProductDao; import com.yefeng.cashapp.model.Product; /** * @author yefengzhichen * 2016年7月15日 */ @Repository(value = "processService") public class ProcessServiceImpl implements ProcessService { @Autowired private ProductDao productDao; public String calculateAll(String inputString){ Map<String, Double> map = parseInput(inputString); return calculatePrice(map); } //解析条形码输入,输入中包含数量,进行分割 public Map<String, Double> parseInput(String inputString) { String[] input = inputString.split(","); Map<String, Double> buy = new HashMap<>(); for (String str : input) { String[] content = str.split("-"); double num = 0.0; if (content.length == 1) { num = 1.0; } else if (content.length == 2) { num = Double.parseDouble(content[1]); } String key = content[0]; if (buy.containsKey(key)) { num += buy.get(key); buy.put(key, num); } else { buy.put(key, num); } } return buy; } //计算总的价格、以及实现满100减10的优惠,最后返回一个小票的字符串 public String calculatePrice(Map<String, Double> buy) { String result; List<Product> productList = productDao.getAll(); String detail = ""; StringBuffer detailPrice = new StringBuffer("` *<没钱赚商店>购物清单*"); StringBuffer discountPrice = new StringBuffer(""); StringBuffer tatalPrice = new StringBuffer(""); double totalSum = 0.0; double discountSum = 0.0; // 小数位数 DecimalFormat df = new DecimalFormat("######0.00"); for (Map.Entry<String, Double> entry : buy.entrySet()) { String barcode = entry.getKey(); Product product = productDao.getByBarcode(barcode); double value = entry.getValue(); double price = product.getPrice(); String name = product.getName(); String unit = product.getUnit(); boolean isDiscount = product.isDiscount(); // String sub = product.getSubCategory(); detailPrice.append(" 名称:" + name + ",数量:" + value + "" + unit + ",单价:" + df.format(price) + "(元)"); double subTotal = value * price; if (isDiscount && subTotal >= 100.0) { double dis = (int) subTotal / 100 * 10; totalSum += subTotal; discountSum += dis; detailPrice.append(",小计:" + df.format(subTotal) + "(元),优惠:" + df.format(dis) + "(元) "); if (discountPrice.length() < 1) { discountPrice.append("单品满100减10块商品:"); } discountPrice.append(" 商品:" + name + ",原价:" + subTotal + "(元),优惠:" + dis + "(元) "); } else { totalSum += subTotal; detailPrice.append(",小计:" + df.format(subTotal) + "(元) "); } } tatalPrice.append("总计:" + df.format(totalSum - discountSum) + "(元)"); if (discountPrice.length() > 1) { tatalPrice.append(" 节省:" + df.format(discountSum) + "(元)"); } result = detailPrice.toString() + "\n" + discountPrice.toString() + "\n" + tatalPrice.toString(); return result; } }
2.6 Controller层
首先是首页控制器,直接返回home.jsp。package com.yefeng.cashapp.web; import static org.springframework.web.bind.annotation.RequestMethod.*; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping(value="/") public class HomeController { @RequestMapping(method=GET) public String home(){ return "home"; } }
Usercontroller,定义了用户注册、登录验证相关的处理:
package com.yefeng.cashapp.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.yefeng.cashapp.dao.ProductDao; import com.yefeng.cashapp.dao.UserDao; import com.yefeng.cashapp.model.Product; import com.yefeng.cashapp.model.User; /** * @author yefengzhichen * 2016年7月15日 */ @Controller @RequestMapping(value = "/user") public class UserController { @Autowired private UserDao userDao; @Autowired private ProductDao productDao; @RequestMapping(value = "/register", method = RequestMethod.GET) public String showRegisterForm() { return "registerForm"; } @RequestMapping(value = "/register", method = RequestMethod.POST) public String processRegister(User user) { userDao.save(user); return "redirect:/user/" + user.getName(); } @RequestMapping(value = "/login", method = RequestMethod.GET) public String showLogin(User user, Model model) { return "login"; } @RequestMapping(value = "/login", method = RequestMethod.POST) public String processLogin(User user, Model model) { boolean valid = userDao.isValid(user); if (!valid) { return "redirect:/user/login"; } /*List<Product> productList = productDao.getAll(); model.addAttribute(productList); String discountList = ""; for (int i = 0; i < productList.size(); ++i) { Product product = productList.get(i); if (product.isDiscount()) { discountList += product.getBarcode(); if (i != productList.size()) { discountList += ", "; } } } String detail = "The input product barcode is null"; model.addAttribute(discountList); model.addAttribute(detail);*/ return "redirect:/start"; } @RequestMapping(value = "/{name}", method = RequestMethod.GET) public String showBloggerProfile(@PathVariable String name, Model model) { User user = userDao.get(name); model.addAttribute(user); return "profile"; } }
ProcessController,处理需要里面的增加商品信息、增加打折商品、计算价格等处理:
package com.yefeng.cashapp.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.yefeng.cashapp.dao.ProductDao; import com.yefeng.cashapp.dao.UserDao; import com.yefeng.cashapp.model.Product; import com.yefeng.cashapp.service.ProcessService; /** * @author yefengzhichen * 2016年7月15日 */ @Controller @RequestMapping(value = "/start") public class ProcessController { @Autowired private UserDao userDao; @Autowired private ProductDao productDao; @Autowired private ProcessService processService; @RequestMapping(method = RequestMethod.GET) public String shopApp(Model model) { addModelAttribute(model); String detail = "The input product barcode is null"; model.addAttribute("detail", detail); return "start"; } // Item0010,apple,kg,fruit,fresh fruit,13.00 @RequestMapping(value = "/inputProduct", method = RequestMethod.POST) public String addProduct(String inputProduct, Model model) { String[] proStr = inputProduct.split(";"); for (String pro : proStr) { String[] list = pro.split(","); String barcode = list[0]; String name = list[1]; String unit = list[2]; String category = list[3]; String subCategory = list[4]; Double price = Double.parseDouble(list[5]); Product product = new Product(barcode, name, unit, category, subCategory, price); productDao.save(product); } addModelAttribute(model); return "start"; } @RequestMapping(value = "/inputDiscount", method = RequestMethod.POST) public String addDiscount(String inputDiscount, Model model) { String[] barcodes = inputDiscount.split(","); for (String barcode : barcodes) { productDao.setDiscount(barcode); } addModelAttribute(model); return "start"; } @RequestMapping(value = "/inputBarcode", method = RequestMethod.POST) public String inputItem(String inputBarcode, Model model) { String detail = processService.calculateAll(inputBarcode); model.addAttribute("datail", detail); addModelAttribute(model); return "start"; } public void addModelAttribute(Model model) { List<Product> productList = productDao.getAll(); model.addAttribute("productList", productList); String discountList = ""; for (int i = 0; i < productList.size(); ++i) { Product product = productList.get(i); if (product.isDiscount()) { if (discountList.length() == 0) { discountList += product.getBarcode(); } else { discountList += (", " + product.getBarcode()); } } } model.addAttribute("discountList", discountList); } }
2.7 View层
在介绍之前,先浏览一下目录结构如下:home.jsp,简单的定义两个链接,分别是注册和登录:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page session="false"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Blog for people who follows your heart</title> </head> <body> <h1 align="center">Welcome to cashapp</h1> <div align="center"> <a style="font-size:16px;" href="<c:url value="/user/login" />">Login</a> <a style="font-size:16px;" href="<c:url value="/user/register" />">Register</a> </div> </body> </html>
RegisterForm,定义注册界面:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page session="false"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>cashapp</title> </head> <body> <h1 align="center">Register</h1> <div align="center"> <form action="/cashapp/user/register" method="post"> <!-- real :action="/cashapp/user/register" --> UserName: <input type="text" name="name" /> <br/> PassWord: <input type="password" name="password" /> <br/> Description: <input type="text" name="description" /> <br/> <input type="submit" value="Register"> </form> </div>> </body> </html>
profile.jsp,显示注册成功的界面,显示名称和介绍:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page session="false"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Blog for people who follows your heart</title> </head> <body> <h4 align="center">Welcome to cashapp</h4> <div align="center"> Your name: <c:out value="${user.name}"></c:out> <br> Your description: <c:out value="${user.description}"></c:out> </div> </body> </html>
start.jsp,收银机系统的主界面,大多数功能处理在此处:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page session="false"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>cashapp</title> </head> <body> <h1 align="center">A brief web cashapp</h1> <p style="FONT-SIZE: 16px" align="center"> Product information list: <br> </p> <!-- 商品信息表格输出 --> <table align="center" border="2"> <tr> <td width="100">barcode</td> <td width="100">name</td> <td width="100">unit</td> <td width="100">category</td> <td width="140">subCategory</td> <td width="100">price</td> </tr> <c:forEach items="${productList}" var="product"> <tr> <td width="100"><c:out value="${product.barcode}" /></td> <td width="100"><c:out value="${product.name}" /></td> <td width="100"><c:out value="${product.unit}" /></td> <td width="100"><c:out value="${product.category}" /></td> <td width="140"><c:out value="${product.subCategory}" /></td> <td width="100"><c:out value="${product.price}" /></td> </tr> </c:forEach> </table> <!-- 输入购买的商品条形码 --> <div align="center"> <br> Input product barcode list(Example:Item0002,Item0010-10): <br> <form action="/cashapp/start/inputBarcode" method="post" id="inputBarcode"> <textarea name="inputBarcode" cols="100" rows="1"></textarea> <br> <input type="submit" value="InputBarcode"> </form> </div> <!-- 输出商品价格详细清单 --> <div align="center"> <br> Output product price details: <br> <textarea rows="6" cols="100"><c:out value="${datail}"></c:out> </textarea> </div> <!-- 输入要增加商品信息/cashapp/start/inputProduct Item0010,apple,kg,fruit,fresh fruit,13.00--> <div align="center"> <br> Input product information list(Example:Item0010,apple,kg,fruit,fresh fruit,13.00): <br> <form action="/cashapp/start/inputProduct" method="post" id="inputProduct"> <textarea name="inputProduct" cols="100" rows="2"></textarea> <br> <input type="submit" value="inputProduct"> </form> </div> <!-- 已经保存的打折商品条形码列表 --> <div align="center"> <br> Discount information list: <br> <textarea rows="2" cols="100"><c:out value="${discountList}"></c:out> </textarea> </div> <!-- 输入要增加的打折商品条形码--> <div align="center"> <br> Input discount product list(Example:Item0002,Item0010): <br> <form action="/cashapp/start/inputDiscount" method="post" id="inputDiscount"> <textarea name="inputDiscount" cols="100" rows="1"></textarea> <br> <input type="submit" value="InputDiscount"> </form> </div> </body> </html>
相关文章推荐
- SCJD考得是你对java性能比较全面得理解
- java中的泛型类型与Type接口
- JAVA FOR ACM 备忘录
- JAVA EE基础教程(5)hibernate的基本使用(视频笔记)
- 关于RxJava学习总结
- java的一些小技巧!
- Ubuntu安装JDK1.8
- Spring4读书笔记(1)-模块
- Eclipse中SVN过滤指定文件夹或文件下内容
- Java中字符串的比较==,equals()方法
- RxJava学习笔记
- 使用Maven运行Java main的3种方式
- Win8系统的Myeclipse远程连接Hadoop配置
- Java基础之(五)Static关键字
- JavaWeb核心编程之使用Eclipse开发JavaWEB项目
- 基于Opencv的Android图像处理(Eclipse和ndk)
- Java入门第三季-学习笔记(上)
- package-info.java文件解读
- Java 学习笔记_1`
- Maven构建SpringMVC项目实现注解、数据库事务管理及存储过程操作