apple添加testflight Apple添加付款方式被拒 您所在的位置:网站首页 testflight被拒绝 apple添加testflight Apple添加付款方式被拒

apple添加testflight Apple添加付款方式被拒

2024-06-30 17:38| 来源: 网络整理| 查看: 265

一、项目的目录结构

apple添加testflight Apple添加付款方式被拒_测试

二、订购流程总体设计

apple添加testflight Apple添加付款方式被拒_测试_02

三、订购流程的详细设计

1.定义基本流程pizza-flow.xml

1 2 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

而且在进入子流程前,必须将订单对象作为子流程的输入进行传递,如果子流程结束的状态ID为customerReady,那么当执行完子流程后就会跳转到名为order的状态。接下来,先介绍customer子流程。

2.子流程customer-flow.xml

1 2 6 7 8 9 10 11 12 13 14 15 16 18 20 21 22 23 24 25 27 28 29 30 31 32 33 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

  第一个进入的流程是由定义的“welcome”视图状态,即用户欢迎界面,需要用户输入电话号码,具体如下图所示,

apple添加testflight Apple添加付款方式被拒_apple添加testflight_03

在welcome状态中有两个用定义的转移,如果触发了phoneEntered事件,即用户输入电话号码,然后点击Lookup Customer按钮后,会跳转到由定义的lookupCustomer行为状态,对用户输入的电话号码进行查询。进入到lookupCustomer状态后,首先使用元素计算了一个表达式(SpEL表达式),将计算结果放在order对象的customer变量中。计算过程就是调用pizzaFlowActions(调用的时候首字母小写)类中的lookupCustomer方法,输入参数就是用户输入的电话号码,通过requestParameters.phoneNumber得到。在lookupCustomer中状态的转移是通过抛出异常触发的,因为如果通过电话号码找不到顾客,说明这个顾客是新客户,需要进行信息登记,所以就会抛出自定义异常CustomerNotFoundException,用来触发下一个流程——用户注册。相反,如果通过电话号码找到了用户,则说明是老顾客,那么就直接跳转到customerReady状态,即第一个Customer流程随之结束,跳转到下一个流程——Order。进入由定义的registrationForm视图状态后,首先通过设置的model属性为表单绑定order对象,具体如下图所示,

apple添加testflight Apple添加付款方式被拒_java_04

然后使用进行切入,即进入registrationForm状态后,先获取前一个页面用户输入的电话号码,通过requestParameters.phoneNumber得到,然后赋值给order.customer.phoneNumber。当用户输入完全部信息后,点击Submit按钮就会通过进行状态转移,转移到checkDeliveryArea状态中。如果点击Cancel就会返回首页。checkDeliveryArea是一个由定义的决策状态,通过表达式的值确定下一步的转移方向,表达式是通过调用pizzaFlowActions类中checkDeliveryArea方法对邮编进行判断。如果表达式结果为ture则转移到then属性指定的addCustomer状态中,如果为false,则转移到else属性指定的deliveryWarning状态中。deliveryWarning状态是由于用户所填写的地址超出配送范围,需要用户到店自取,判断用户是否接受这个请求,具体如下图所示。

apple添加testflight Apple添加付款方式被拒_apple添加testflight_05

如果用户点击Accept则会跳转到addCustomer状态中,点击cancel就会返回首页。addCustomer状态是一个行为状态,使用表达式将刚注册的用户信息进行保存,然后跳转到customerReady状态,即子流程的结束状态,最后返回到主流程中,第一个customer流程执行完毕,跳转到order流程。

  同样进入到order流程后,会跳转到子流程order-flow,也会需要一个订单对象作为输入。如果子流程结束的状态ID为orderCreated,那么子流程执行完毕会跳转到payment状态。具体的流程下面进行详细介绍。

3.子流程order-flow.xml

1 2 6 7 8 9 10 11 12 13 14 15 16 17 18 20 22 23 24 25 26 27 28 29 30 31 32 33

首先进入showOrder状态,其中包含三个可以进行转移的状态:createPizza,orderCreated,cancel。showOrder是一个视图状态,对应的页面如下图所示:

apple添加testflight Apple添加付款方式被拒_java_06

当用户点击Create Pizza按钮后,触发createPizza状态,因为createPizza页面中也有表单,所以先设置model属性进行表单与pizza对象进行绑定。需要注意的是这里的pizza对象的作用域范围是flow,即当流程开始时创建,在流程结束时销毁。只有在创建它的流程中是可见的。在进入createPizza流程后,先设置两个变量。第一个变量是pizza,作用域是flow,通过设置,用于保存pizza信息,当表单提交时,表单的内容会填充到该对象中。需要注意的是,这个视图状态引用的model是流程作用域内的同一个Pizza对象。第二个是toppingsList,作用域是view,即当进入视图状态时创建,当这个状态退出时销毁,只在视图状态内时可见的,所以flow>view。toppingsList是用来保存披萨的种类的。具体的createPizza对应的页面如下所示:

apple添加testflight Apple添加付款方式被拒_apple添加testflight_07

 

当用户选择完披萨的大小和种类后,点击Continue按钮后,通过触发addPizza进入到视图showOrder,在重新进入showOrder视图的时候,将刚才填充完毕的pizza对象加入到order对象当中,现在的order就不为空了,具体如下图所示:

apple添加testflight Apple添加付款方式被拒_web.xml_08

当用户点击Checkout按钮时,转移到orderCreated状态,意味着order子流程的结束,需要跳转到payment流程。下面再对payment流程进行介绍。

4.子流程payment-flow.xml

1 2 6 7 8 9 10 11 13 15 16 17 18 19 20 21 23 24 25 26 27 28 29

首先进入takePayment流程当中,先初始化两个变量。一个是flow级作用域的paymentDetails,另一个是view级的paymentTypeList。takePayment对应的页面如下所示:

apple添加testflight Apple添加付款方式被拒_java_09

  当用户点击Submit触发paymentSubmitted,然后转移到verifyPayment行为状态。verifyPayment主要是通过调用pizzaFlowActions类的verifyPayment方法对用户的支付类型进行判断。最后转移到paymentTaken状态,意味着子流程结束,返回到主流程中。

主流程中和payment相关的流程还有一个行为状态saveOrder,顾名思义将上述流程创建的订单进行保存,然后转移到thankCustomer状态。thankCustomer界面如下所示:

apple添加testflight Apple添加付款方式被拒_java_10

当点击finish就又跳转到首页,重新开始整个流程。

四、具体实现

Spring Web Flow 就是 Spring Web MVC 的一个扩展,如果粗略一些来讲,所谓 flow 就相当于 Spring Web MVC 中一种特殊的 controller ,这种 controller 可通过 XML 文件加以配置。所以必须对Spring Web MVC进行配置,然后再定义相应的flow。

(一)通过Java来配置SpringMVC,但是flow不能通过java配置,必须通过xml来进行配置。使用Java配置的目的是显示欢迎页面。

1.在src/main/java目录下分别创建两个包,一个是spizza.config用来配置SpringMVC,另一个是spizza.controller用来配置控制器。目录结构如下所示:

apple添加testflight Apple添加付款方式被拒_web.xml_11

RootConfig.java

1 package spizza.config; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.ComponentScan.Filter; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.FilterType; 7 import org.springframework.web.servlet.config.annotation.EnableWebMvc; 8 9 @Configuration("RootConfig") 10 @ComponentScan(basePackages = { "spizza" }, excludeFilters = { 11 @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) }) 12 public class RootConfig { 13 14 }

SpizzaWebApplnitializer.java

1 package spizza.config; 2 3 import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 4 5 public class SpizzaWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 6 7 @Override 8 protected Class[] getRootConfigClasses() { 9 // TODO Auto-generated method stub 10 return new Class[] { RootConfig.class }; 11 } 12 13 @Override 14 protected Class[] getServletConfigClasses() { 15 // TODO Auto-generated method stub 16 return new Class[] { WebConfig.class }; 17 } 18 19 @Override 20 protected String[] getServletMappings() { 21 // TODO Auto-generated method stub 22 return new String[] { "/" }; 23 } 24 }

WebConfig.java

1 package spizza.config; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.ComponentScan; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; 7 import org.springframework.web.servlet.config.annotation.EnableWebMvc; 8 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 import org.springframework.web.servlet.view.InternalResourceViewResolver; 10 11 @Configuration("WebConfig") 12 @EnableWebMvc 13 @ComponentScan("spizza.controller") 14 public class WebConfig extends WebMvcConfigurerAdapter { 15 @Bean 16 public InternalResourceViewResolver viewResolver() { 17 InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 18 resolver.setPrefix("/WEB-INF/view/"); 19 resolver.setSuffix(".jsp"); 20 resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class); 21 resolver.setExposeContextBeansAsAttributes(true); 22 return resolver; 23 } 24 25 @Override 26 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 27 // TODO Auto-generated method stub 28 configurer.enable(); 29 } 30 31 }

HomeController.java

1 package spizza.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.RequestMethod; 6 7 @Controller 8 public class HomeController { 9 public HomeController() { 10 } 11 12 @RequestMapping(value = "welcome", method = RequestMethod.GET) 13 public String home() { 14 return "index"; 15 } 16 }

 

通过Java来配置SpringMVC也是一种复习回顾,Spring实战中推荐使用Java配置。

2.运行结果:

apple添加testflight Apple添加付款方式被拒_java_12

(二)配置Spring Web Flow

在WEB-IN目录下创建spring文件夹,用来存放有关flow的配置,在WEB-IN目录下创建flows文件夹,用来存放具体的flow流程。具体目录结构如下所示:

apple添加testflight Apple添加付款方式被拒_java_13

1.基础配置,将不同作用的配置文件分开,然后在root-config.xml中进行导入。

flow.xml

1 2 12 13 14 15 16 17 18 19 21 23 25 27 29 30 31 33 34 36 37 38 39

mvc.xml

1 2 6 8 10 11 12 13 14 15 16 18 19 20 /pizza-flow.do=flowController 21 22 23 24 25 26

domain.xml,加载流程中需要的bean。

1 2 3 10 11 12 13 14 15 16 17

services.xml,加载流程中需要的bean。

1 2 3 7 8 10 11 15 16 18 19 20 22 23 25 26

root-config.xml

1 2 6 7 8 9 10 11 12 13

web.xml,虽然以及使用Java配置过Servlet,参考SpizzaWebAppInitializer.java,但是为了执行flow,还需要在web.xml中进行相应的配置。

1 5 6 CartServlet 7 org.springframework.web.servlet.DispatcherServlet 8 9 contextConfigLocation 10 11 /WEB-INF/spring/root-config.xml 12 13 14 1 15 16 17 CartServlet 18 *.do 19 20

2.Flow的定义

整个顾客订购披萨的过程可以分为三个部分,第一部分就是顾客相关信息验证以及查询,第二个部分是订单的创建,第三个部分是支付。所以不应该将全部的流程都放在一个文件中进行定义,应该分别定义为子流程,然后在主流程中进行调用。具体内容参照第三小节。

(三)视图,只给出了主要内容。

1.index.jsp

1 Hello! 2 Spizza

2.welcome.jsp

1 Welcome to Spizza!!! 2 3 4 5 phoneNumber 6 9 10 11 12 14 15 16 17

3.registrationForm.jsp

1 Customer Registration 2 3 4 5 7 8 9 Phone number: 10 11 12 13 Name: 14 15 16 17 Address: 18 19 20 21 State: 22 23 24 25 Zip Code: 26 27 28 29 30      32 33 34 35

4.deliveryWarning.jsp

1 Delivery Unavailable 2 3

The address is outside of our delivery area. The order may still be taken for carry-out.

4 5 Accept | 6 Cancel

5.showOrder.jsp

1 2 Your order 3 4 Deliver to: 5 6 7 name 8 ${order.customer.name} 9 10 11 address 12 ${order.customer.address} 13 14 15 city 16 ${order.customer.city} 17 18 19 state 20 ${order.customer.state} 21 22 23 zipCode 24 ${order.customer.zipCode} 25 26 27 phoneNumber 28 ${order.customer.phoneNumber} 29 30 31 32 33 Order total: 34 35 36 37 38 Pizzas: 39 40 41 No pizzas in this order. 42 43 44 45 46 47 Size 48 Toppings 49 IsCombo 50 Price 51 52 53 54 ${pizza.size} 55 56 57 58 59 60 ${pizza.isCombo } 61 62 ${pizza.price } 63 64 65 66 67 68 70 71 72 73 74 75 76

6.createPizza.jsp

1 2 3 Create Pizza 4 5 7 8 Size: 9 10 11 12 14 15 16 18 19 20 22 23 24 26 27 28 29 30 Toppings: PRICE_PER_TOPPING 0.20¥ 31 32 33 34 35 37 38 39 40 41 42 Hyperchannel 43 44 45 47 48 49 51 52 53 55 56 57 59 61 62

7.takePayment.jsp

1 2 3 4 function showCreditCardField() { 5 var ccNumberStyle = document.paymentForm.creditCardNumber.style; 6 ccNumberStyle.visibility = 'visible'; 7 } 8 9 function hideCreditCardField() { 10 var ccNumberStyle = document.paymentForm.creditCardNumber.style; 11 ccNumberStyle.visibility = 'hidden'; 12 } 13 14 15 Take Payment 16 17 18 19 21 22 23 25 26 27 29 30 31 33 35 36 37 38 40      42 43 44 45 46

8.thankCustomer.jsp

 

1 Thank you for your order! 2 付款方式 3 ${order.payment} 4 5 Finish

 

(四)后台

1.用于保存信息的类Customer,Pizza,PaymentDetails,Order。

Customer保存用户的姓名、地址、城市、详细地址、邮政编码、电话号码等。

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 5 @SuppressWarnings("serial") 6 public class Customer implements Serializable { 7 private Integer id; 8 private String name; 9 private String address; 10 private String city; 11 private String state; 12 private String zipCode; 13 private String phoneNumber; 14 15 public Customer() { 16 } 17 18 public Customer(String phoneNumber) { 19 this.phoneNumber = phoneNumber; 20 } 21 22 public String getCity() { 23 return city; 24 } 25 26 public void setCity(String city) { 27 this.city = city; 28 } 29 30 public Integer getId() { 31 return id; 32 } 33 34 public void setId(Integer id) { 35 this.id = id; 36 } 37 38 public String getName() { 39 return name; 40 } 41 42 public void setName(String name) { 43 this.name = name; 44 } 45 46 public String getPhoneNumber() { 47 return phoneNumber; 48 } 49 50 public void setPhoneNumber(String phoneNumber) { 51 this.phoneNumber = phoneNumber; 52 } 53 54 public String getState() { 55 return state; 56 } 57 58 public void setState(String state) { 59 this.state = state; 60 } 61 62 public String getAddress() { 63 return address; 64 } 65 66 public void setAddress(String address) { 67 this.address = address; 68 } 69 70 public String getZipCode() { 71 return zipCode; 72 } 73 74 public void setZipCode(String zipCode) { 75 this.zipCode = zipCode; 76 } 77 }

Pizza保存披萨的大小、添加的配料、价格等信息。

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 import java.util.List; 5 6 @SuppressWarnings("serial") 7 public class Pizza implements Serializable { 8 private PizzaSize size; 9 private List toppings; 10 private List specialPizza; 11 private String isCombo; 12 private float price; 13 14 public Pizza() { 15 size = PizzaSize.LARGE; 16 } 17 18 public float getPrice() { 19 return price; 20 } 21 22 public void setPrice(float price) { 23 this.price = price; 24 } 25 26 public String getIsCombo() { 27 return isCombo; 28 } 29 30 public void setIsCombo(String isCombo) { 31 this.isCombo = isCombo; 32 } 33 34 public List getSpecialPizza() { 35 return specialPizza; 36 } 37 38 public void setSpecialPizza(List specialPizza) { 39 this.specialPizza = specialPizza; 40 } 41 42 public PizzaSize getSize() { 43 return size; 44 } 45 46 public void setSize(PizzaSize size) { 47 this.size = size; 48 } 49 50 public void setSize(String sizeString) { 51 this.size = PizzaSize.valueOf(sizeString); 52 } 53 54 public List getToppings() { 55 return toppings; 56 } 57 58 public void setToppings(List toppings) { 59 this.toppings = toppings; 60 } 61 62 public void setToppings(String[] toppingStrings) { 63 for (int i = 0; i < toppingStrings.length; i++) { 64 toppings.add(Topping.valueOf(toppingStrings[i])); 65 } 66 } 67 }

  因为在披萨选择页面顾客可以自行选择配料,也可以直接选择已经提供好的套餐,用户可以自由选择。所以在Pizza类中会有specialPizza字段用来存放顾客是否选择了套餐。

  其中PizzaSize和Topping都是自定义的枚举类型的类,用来存放披萨大小和配料种类,具体如下所示:

PizzaSize.java

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 5 public enum PizzaSize implements Serializable { 6 SMALL, MEDIUM, LARGE, GINORMOUS; 7 }

Topping.java

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 import java.util.Arrays; 5 import java.util.List; 6 7 import org.apache.commons.lang3.text.WordUtils; 8 9 public enum Topping implements Serializable { 10 PEPPERONI, SAUSAGE, HAMBURGER, MUSHROOM, CANADIAN_BACON, PINEAPPLE, GREEN_PEPPER, JALAPENO, TOMATO, ONION, EXTRA_CHEESE; 11 12 public static List asList() { 13 Topping[] all = Topping.values(); 14 return Arrays.asList(all); 15 } 16 17 @Override 18 public String toString() { 19 return WordUtils.capitalizeFully(name().replace('_', ' ')); 20 } 21 }

PaymentDetails保存顾客的付款信息,其中主要包括付款类型,以及卡号(如果使用信用卡)。

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 5 public class PaymentDetails implements Serializable { 6 private static final long serialVersionUID = 1L; 7 8 private PaymentType paymentType; 9 private String creditCardNumber; 10 11 public PaymentType getPaymentType() { 12 return paymentType; 13 } 14 15 public void setPaymentType(PaymentType paymentType) { 16 this.paymentType = paymentType; 17 } 18 19 public String getCreditCardNumber() { 20 return creditCardNumber; 21 } 22 23 public void setCreditCardNumber(String creditCardNumber) { 24 this.creditCardNumber = creditCardNumber; 25 } 26 }

其中PaymentType是自定义的一个枚举类型的类,用来存放支付的方式,具体如下所示:

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.util.Arrays; 4 import java.util.List; 5 6 import org.apache.commons.lang3.text.WordUtils; 7 8 public enum PaymentType { 9 CASH, CHECK, CREDIT_CARD; 10 11 public static List asList() { 12 PaymentType[] all = PaymentType.values(); 13 return Arrays.asList(all); 14 } 15 16 @Override 17 public String toString() { 18 return WordUtils.capitalizeFully(name().replace('_', ' ')); 19 } 20 }

Order类中保存整个订单的信息。

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import org.springframework.beans.factory.annotation.Configurable; 8 import org.springframework.util.StringUtils; 9 10 import main.java.com.springinaction.pizza.flow.SpecialtyPizza; 11 import main.java.com.springinaction.pizza.service.PricingEngineImpl; 12 13 @Configurable("order") 14 public class Order implements Serializable { 15 private static final long serialVersionUID = 1L; 16 private Customer customer; 17 private List pizzas; 18 private Payment payment; 19 20 public Order() { 21 pizzas = new ArrayList(); 22 customer = new Customer(); 23 } 24 25 public Customer getCustomer() { 26 return customer; 27 } 28 29 public void setCustomer(Customer customer) { 30 this.customer = customer; 31 } 32 33 public List getPizzas() { 34 return pizzas; 35 } 36 37 public void setPizzas(List pizzas) { 38 this.pizzas = pizzas; 39 } 40 41 public void addPizza(Pizza pizza) { 42 // System.out.println(StringUtils.isEmpty(pizza.getToppings())); 43 // System.out.println(StringUtils.isEmpty(pizza.getSpecialPizza())); 44 45 Boolean pizza1 = StringUtils.isEmpty(pizza.getToppings()); 46 Boolean pizza2 = StringUtils.isEmpty(pizza.getSpecialPizza()); 47 48 if (pizza1 == false && pizza2 == true) { 49 pizza.setIsCombo("—"); 50 pizzas.add(pizza); 51 } else if (pizza1 == true && pizza2 == false) { 52 SpecialtyPizza specialtyPizza = new SpecialtyPizza(); 53 List newPizzas = specialtyPizza.getPizza(pizza); 54 for (Pizza temp : newPizzas) { 55 pizzas.add(temp); 56 } 57 } else if (pizza1 == false && pizza2 == false) { 58 pizza.setIsCombo("—"); 59 pizzas.add(pizza); 60 SpecialtyPizza specialtyPizza = new SpecialtyPizza(); 61 List newPizzas = specialtyPizza.getPizza(pizza); 62 for (Pizza temp : newPizzas) { 63 pizzas.add(temp); 64 } 65 } 66 } 67 68 public float getTotal() { 69 PricingEngineImpl pricingEngineImpl = new PricingEngineImpl(); 70 List pizzas = this.getPizzas(); 71 72 return pricingEngineImpl.calculateOrderTotal(pizzas); 73 } 74 75 public Payment getPayment() { 76 return payment; 77 } 78 79 public void setPayment(Payment payment) { 80 this.payment = payment; 81 payment.setAmount(this.getTotal()); 82 } 83 84 }

需要注意的是在添加披萨到订单当中时,即方法addPizza,其参数是一个Pizza类型的列表。因为在表单中直接绑定了pizza的三个对象,size、topping和specialPizza,而其中topping与specialPizza可以不用同时赋值,所以再添加pizza对象到订单中的时候要对这两个对象判断是否为空,然后根据实际情况添加相应的pizza对象到订单当中。所以还需要一个SpecialtyPizza类返回特殊的pizza对象,具体如下所示:

1 package main.java.com.springinaction.pizza.flow; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import main.java.com.springinaction.pizza.domain.Pizza; 7 import main.java.com.springinaction.pizza.domain.Topping; 8 9 public class SpecialtyPizza { 10 11 public List getPizza(Pizza pizza) { 12 List newPizza = new ArrayList(); 13 if (pizza.getSpecialPizza().size() != 0) { 14 for (String type : pizza.getSpecialPizza()) { 15 if ("MEAT".equals(type)) { 16 17 List meats = new ArrayList(); 18 19 meats.add(Topping.CANADIAN_BACON); 20 meats.add(Topping.HAMBURGER); 21 meats.add(Topping.PEPPERONI); 22 meats.add(Topping.SAUSAGE); 23 Pizza tempt = new Pizza(); 24 tempt.setSize(pizza.getSize()); 25 tempt.setToppings(meats); 26 tempt.setIsCombo("MEAT"); 27 newPizza.add(tempt); 28 } else if ("VEGGIE".equals(type)) { 29 30 List meats = new ArrayList(); 31 32 meats.add(Topping.GREEN_PEPPER); 33 meats.add(Topping.MUSHROOM); 34 meats.add(Topping.PINEAPPLE); 35 meats.add(Topping.TOMATO); 36 37 Pizza tempt = new Pizza(); 38 tempt.setSize(pizza.getSize()); 39 tempt.setToppings(meats); 40 tempt.setIsCombo("VEGGIE"); 41 newPizza.add(tempt); 42 } else if ("THEWORKS".equals(type)) { 43 44 List meats = new ArrayList(); 45 System.out.println("THE WORKS!"); 46 47 meats.add(Topping.CANADIAN_BACON); 48 meats.add(Topping.HAMBURGER); 49 meats.add(Topping.PEPPERONI); 50 meats.add(Topping.SAUSAGE); 51 meats.add(Topping.GREEN_PEPPER); 52 meats.add(Topping.MUSHROOM); 53 meats.add(Topping.PINEAPPLE); 54 meats.add(Topping.TOMATO); 55 meats.add(Topping.EXTRA_CHEESE); 56 meats.add(Topping.ONION); 57 meats.add(Topping.JALAPENO); 58 59 Pizza tempt = new Pizza(); 60 tempt.setSize(pizza.getSize()); 61 tempt.setToppings(meats); 62 tempt.setIsCombo("THEWORKS"); 63 newPizza.add(tempt); 64 } 65 } 66 return newPizza; 67 } else { 68 return newPizza; 69 } 70 } 71 }

在初始化payment对象时,同时用订单总金额来初始化payment对象中amount变量,其中的payment是一个抽象类的实例,代码如下所示:

Payment.java

 

1 package main.java.com.springinaction.pizza.domain; 2 3 import java.io.Serializable; 4 5 public abstract class Payment implements Serializable { 6 private static final long serialVersionUID = 1L; 7 8 private float amount; 9 private String creditCardNumber; 10 11 public String getCreditCardNumber() { 12 return creditCardNumber; 13 } 14 15 public void setCreditCardNumber(String creditCardNumber) { 16 this.creditCardNumber = creditCardNumber; 17 } 18 19 public void setAmount(float amount) { 20 this.amount = amount; 21 } 22 23 public float getAmount() { 24 return amount; 25 } 26 }

 

这个抽象类主要包含两个成员变量:amount(需要付款的总金额),creditCardNumber(使用信用卡付款时的卡号)。然后添加了两个类CshOrCheckPayment和CreditCardPayment,它们都继承Payment。

CshOrCheckPayment

 

1 package main.java.com.springinaction.pizza.domain; 2 3 public class CashOrCheckPayment extends Payment { 4 public CashOrCheckPayment() { 5 } 6 7 public String toString() { 8 return "CASH or CHECK: ¥" + getAmount(); 9 } 10 }

 

CreditCardPayment

 

1 package main.java.com.springinaction.pizza.domain; 2 3 public class CreditCardPayment extends Payment { 4 public CreditCardPayment() { 5 } 6 7 public String toString() { 8 return "CREDIT: ¥" + getAmount() + " ; AUTH: " + this.getCreditCardNumber(); //调用父类的成员变量 9 } 10 }

 

 

2.流程执行过程中需要用到的方法。

CustomerServiceImpl,实现CustomerService接口,接口中只有一个方法,lookupCustomer。

1 package main.java.com.springinaction.pizza.service; 2 3 import main.java.com.springinaction.pizza.domain.Customer; 4 5 public class CustomerServiceImpl implements CustomerService { 6 public CustomerServiceImpl() { 7 } 8 9 public Customer lookupCustomer(String phoneNumber) throws CustomerNotFoundException { 10 if ("9725551234".equals(phoneNumber)) { 11 Customer customer = new Customer(); 12 customer.setId(123); 13 customer.setName("Craig Walls"); 14 customer.setAddress("3700 Dunlavy Rd"); 15 customer.setCity("Denton"); 16 customer.setState("TX"); 17 customer.setZipCode("76210"); 18 customer.setPhoneNumber(phoneNumber); 19 return customer; 20 } else { 21 throw new CustomerNotFoundException(); 22 } 23 } 24 }

OrderServiceImpl将用户订单保存到日志当中,因为没有连接数据库。

1 package main.java.com.springinaction.pizza.service; 2 3 import org.apache.log4j.Logger; 4 5 import main.java.com.springinaction.pizza.domain.Order; 6 7 public class OrderServiceImpl { 8 private static final Logger LOGGER = Logger.getLogger(OrderServiceImpl.class); 9 10 public OrderServiceImpl() { 11 } 12 13 public void saveOrder(Order order) { 14 LOGGER.debug("SAVING ORDER: "); 15 LOGGER.debug(" Customer: " + order.getCustomer().getName()); 16 LOGGER.debug(" # of Pizzas: " + order.getPizzas().size()); 17 LOGGER.debug(" Payment: " + order.getPayment()); 18 } 19 }

PricingEngineImpl实现PricingEngine接口,接口中只有一个方法calculateOrderTotal,计算每个披萨的价格,以及订单中披萨的总价。

1 package main.java.com.springinaction.pizza.service; 2 3 import java.io.Serializable; 4 import java.util.HashMap; 5 import java.util.List; 6 import java.util.Map; 7 8 import org.apache.log4j.Logger; 9 10 import main.java.com.springinaction.pizza.domain.Pizza; 11 import main.java.com.springinaction.pizza.domain.PizzaSize; 12 13 @SuppressWarnings("serial") 14 public class PricingEngineImpl implements PricingEngine, Serializable { 15 private static final Logger LOGGER = Logger.getLogger(PricingEngineImpl.class); 16 17 private static Map SIZE_PRICES; 18 static { 19 SIZE_PRICES = new HashMap(); 20 SIZE_PRICES.put(PizzaSize.SMALL, 7.00f); 21 SIZE_PRICES.put(PizzaSize.MEDIUM, 8.00f); 22 SIZE_PRICES.put(PizzaSize.LARGE, 9.00f); 23 SIZE_PRICES.put(PizzaSize.GINORMOUS, 10.00f); 24 } 25 private static float PRICE_PER_TOPPING = 2.00f; 26 27 public PricingEngineImpl() { 28 } 29 30 public float calculateOrderTotal(List pizzas) { 31 32 float total = 0.0f; 33 if (pizzas.size() == 0) { 34 return total; 35 } else { 36 for (Pizza pizza : pizzas) { 37 float pizzaPrice = SIZE_PRICES.get(pizza.getSize()); 38 if (pizza.getToppings().size() > 0) { 39 pizzaPrice += (pizza.getToppings().size() * PRICE_PER_TOPPING); 40 } 41 pizza.setPrice(pizzaPrice); 42 total += pizzaPrice; 43 } 44 45 return total; 46 } 47 } 48 49 }

3.在执行总流程中调用所需的方法时通过PizzaFlowActions类。

1 package main.java.com.springinaction.pizza.flow; 2 3 import org.apache.log4j.Logger; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.stereotype.Service; 6 7 import main.java.com.springinaction.pizza.domain.CashOrCheckPayment; 8 import main.java.com.springinaction.pizza.domain.CreditCardPayment; 9 import main.java.com.springinaction.pizza.domain.Customer; 10 import main.java.com.springinaction.pizza.domain.Order; 11 import main.java.com.springinaction.pizza.domain.Payment; 12 import main.java.com.springinaction.pizza.domain.PaymentDetails; 13 import main.java.com.springinaction.pizza.domain.PaymentType; 14 import main.java.com.springinaction.pizza.service.CustomerNotFoundException; 15 import main.java.com.springinaction.pizza.service.CustomerService; 16 17 @Service 18 public class PizzaFlowActions { 19 20 private static final Logger LOGGER = Logger.getLogger(PizzaFlowActions.class); 21 22 public Customer lookupCustomer(String phoneNumber) throws CustomerNotFoundException { 23 Customer customer = customerService.lookupCustomer(phoneNumber); 24 if (customer != null) { 25 return customer; 26 } else { 27 throw new CustomerNotFoundException(); 28 } 29 } 30 31 public void addCustomer(Customer customer) { 32 LOGGER.warn("TODO: Flesh out the addCustomer() method."); 33 } 34 35 public Payment verifyPayment(PaymentDetails paymentDetails) { 36 Payment payment = null; 37 if (paymentDetails.getPaymentType() == PaymentType.CREDIT_CARD) { 38 payment = new CreditCardPayment(); 39 } else { 40 payment = new CashOrCheckPayment(); 41 } 42 43 return payment; 44 } 45 46 public void saveOrder(Order order) { 47 LOGGER.warn("TODO: Flesh out the saveOrder() method."); 48 } 49 50 public boolean checkDeliveryArea(String zipCode) { 51 LOGGER.warn("TODO: Flesh out the checkDeliveryArea() method."); 52 return "75075".equals(zipCode); 53 } 54 55 @Autowired 56 CustomerService customerService; 57 }

五、程序源码

https://github.com/lyj8330328/Spizza.git



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有