Coffee Shop Project
Merhaba Arkadaslar
Bu bolumde Coffee Shop projesi yapacagiz.
Projemizde kullanacagimiz frameworkler/toollar
- Eclipse
- JDK8
- Spring Framework MVC
- Hibernate Native
- HyperSQL Database
- Maven
- Bootstrap
- JSP
- Log4J
- Apache Tomcat
- Jetty Plugin
NOT0 : Zamanla bu yazida ve projede iyilestirmeler yapacagim insallah.
NOT1: Gordugunuz eksiklikleri/yanlisliklari bildirebilirsiniz. Sorularinizi sorabilirsiniz , zamanla eklemeler aciklamalari bol miktar eklerim. Simdilik initial version olarak dusunebiliriz.
NOT2 : Burada yer alan bir cok konu blogta diger bolumlerde yer almaktadir.
Spring MVC
Github Source / Project
eventerguder/injavawetrust.coffeeshop
Create a Maven Project
Oncelikle yeni bir Maven projesi olusturalim.
NOT : Dynamic Web Project olusturup Convert To Maven yapabilirsiniz.
Jetty Plugin ile direkt calistirmak icin bu formatta olusturdum.
Projemizi olusturduk ;
Sonrasinda yeni bir Folder olusturalim ; src/main/java
Dikkat edecek olursak Projemizde JRE versiyonu 1.5 , bunu guncellemek icin pom.xml dosyamiza yeni bir plugin ekleyelim.
pom.xml
<build> <finalName>injavawetrust.coffeeshop</finalName> <plugins> <plugin> <!-- JDK version --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>${java.specification.version}</source> <target>${java.specification.version}</target> </configuration> </plugin> </plugins> </build>
Sonrasinda ;
right click -> Maven -> Update Project
Add Dependencies
Projemizde kullanacagimiz dependency tanimlarini ve Jetty plugin’i ekleyelim.
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</groupId> <artifactId>injavawetrust.coffeeshop</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>injavawetrust.coffeeshop Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>4.3.2.RELEASE</spring.version> <hibernate.version>5.2.1.Final</hibernate.version> <hsqldb.version>2.3.4</hsqldb.version> <jstl.version>1.2</jstl.version> <log4j.version>1.2.17</log4j.version> <commons.dbcp2.version>2.1.1</commons.dbcp2.version> <servlet.version>3.1.0</servlet.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- spring dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <!-- hibernate dependency --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/jstl/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hsqldb/hsqldb --> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>${hsqldb.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>${commons.dbcp2.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> </dependency> </dependencies> <build> <finalName>injavawetrust.coffeeshop</finalName> <plugins> <plugin> <!-- JDK version --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>${java.specification.version}</source> <target>${java.specification.version}</target> </configuration> </plugin> <!-- embedded Jetty server --> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.11.v20150529</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <webApp> <contextPath>/injavawetrust.coffeeshop</contextPath> </webApp> </configuration> </plugin> </plugins> </build> </project>
Deployment Descriptor
web.xml dosyamizda DispatcherServlet tanimini yapalim.
Projemizin Dynamic Web Module ayarini guncelleyelim ; bunun icin suraya bakabilirsiniz ;
JSF – 07 – Apache TomEE & Project Facets & Maven
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>injavawetrust.coffeeshop</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/application-context.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
application-context.xml
JSP sayfalarimiz WEB-INF/pages dizininde yer alacak. InternalResourceViewResolver bean tanimini ve diger konfigurasyon dosyalarini import edelim.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="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 "> <import resource="db-hsqldb-config.xml" /> <import resource="i18n.xml" /> <import resource="hibernate-config.xml" /> <import resource="interceptors.xml" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
db-hsqldb-config.xml
Veritabani icin HSQL kullanacagiz. Bu noktada .properties ve .sql dosyalarimizi ilgili dizine ekleyecegiz ; /src/main/resources
<?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:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd "> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:jdbc/jdbc.properties</value> </property> </bean> <bean id="dataSourceHSQL" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <jdbc:initialize-database data-source="dataSourceHSQL" ignore-failures="ALL"> <jdbc:script location="classpath:db/sql/create-db.sql" /> <jdbc:script location="classpath:db/sql/insert-data.sql" /> </jdbc:initialize-database> </beans>
jdbc.properties
Dikkat edecek olursak #{systemProperties} Expression yardimi ile veritabani dosyamizi olusturacagimiz path’i ayarliyoruz.
Boylece projemiz portable olabilir , proje calistigi noktada user.home dizini altinda /db/data altinda dosyalar olusacaktir.
jdbc.driverClassName=org.hsqldb.jdbcDriver jdbc.url=jdbc:hsqldb:file:#{systemProperties['user.home']}/db/data jdbc.username=sa jdbc.password=
create-db.sql
Projemiz ayaga kalkarken , Product adinda bir tablo oluracagiz ve bazi kayitlar ekleyecegiz.
CREATE TABLE IF NOT EXISTS Product ( id INTEGER PRIMARY KEY, name VARCHAR(50), description VARCHAR(50), price NUMERIC, isCondiment BOOLEAN, category VARCHAR(50) );
insert-data.sql
Ornek kayitlarimizi ekleyelim. Burada isCondiment kolonunda true icin bu urun tek basina satilabilir , false icin bu urun tek basina satilamaz bir eklenti ozelligi gosteriyor amacli flag tutmaktayiz.
Ilk etapta category olarak da hot , cold , other gibi secenekler olabilir.
insert into Product(id,name,description,price,isCondiment,category) values (1,'Latte','Best Latte',5.00,false,'hot'); insert into Product(id,name,description,price,isCondiment,category) values (2,'Mocha','Best Mocha',6.00,false,'hot'); insert into Product(id,name,description,price,isCondiment,category) values (3,'Cay','Best Cay',3.00,false,'hot'); insert into Product(id,name,description,price,isCondiment,category) values (4,'Turk kahvesi','Best Turk kahvesi',5.00,false,'hot'); insert into Product(id,name,description,price,isCondiment,category) values (5,'Sut','Best Süt',2.00,true,'other'); insert into Product(id,name,description,price,isCondiment,category) values (6,'Findik surubu','Best Findik',3.00,true,'other'); insert into Product(id,name,description,price,isCondiment,category) values (7,'Cikolata sosu','Best Cikolata',5.00,true,'other'); insert into Product(id,name,description,price,isCondiment,category) values (8,'Limon','Best Eksi Limon',2.00,true,'other');
hibernate-config.xml
Hibernate icin LocalSessionFactoryBean ve HibernateTransactionManager bean tanimlarini gerceklestirelim.
Ilgili konuyu surada inceledim ;
Spring MVC – 24 – Hibernate
dataSource property icin , db-hsqldb-config.xml dosyamizda tanimladigimiz dataSourceHSQL id bilgisini veriyoruz.
<?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSourceHSQL" /> <property name="packagesToScan" value="product.domain" /> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </beans>
i18n.xml
Internationalization(i18n) icin konfigurasyonumuzu gerceklestirelim ve springMessages dosyalarini ekleyelim.
i18n konusunu surada inceledim ;
Spring MVC – 10 – Internationalization (i18n) and Localization (L10n)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="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 "> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="springMessages" /> <property name="defaultEncoding" value="UTF-8" /> </bean> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> <property name="defaultLocale" value="tr" /> </bean> </beans>
springMessages_en.properties
Projemizde kullanacagimiz mesajlarin EN karsiligi.
product.products= Products product.add.newproduct = Add new product product.id=Product Id product.name= Name product.price = Price .... more messages
springMessages_tr.properties
Projemizde kullanacagimiz mesajlarin TR karsiligi.
product.products= Ürünler product.add.newproduct= Ürün Ekle product.id= Ürün Kodu product.name= Ürün İsmi product.price = Ürün Fiyatı .... more messages
Audit & Interceptor
Ilgili konuyu burada inceledim ;
Spring MVC – 13 – Interceptors & Log4J
<?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" xsi:schemaLocation=" 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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd "> <context:component-scan base-package="product" /> <mvc:resources mapping="/resources/**" location="/resources/" /> <mvc:annotation-driven /> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> <property name="defaultLocale" value="tr" /> </bean> <mvc:interceptors> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="language" /> </bean> <bean id="audit" class="product.logging.AuditLoggingInterceptor" /> </mvc:interceptors> </beans>
AuditLoggingInterceptor.java
package product.logging; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class AuditLoggingInterceptor extends HandlerInterceptorAdapter { Logger logger = Logger.getLogger("auditLogger"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String remoteHost = request.getRemoteHost(); int remotePort = request.getRemotePort(); logger.info("client host : " + remoteHost); logger.info("client port : " + remotePort); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } }
Product Domain
Product.java , CondimentDecorator.java ve ProductInterface.java sinif ve arabirim ile Decorator Pattern’i uygulayalim.
Product.java
package product.domain; import java.math.BigDecimal; import java.util.LinkedHashMap; import java.util.Map; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.TableGenerator; import javax.persistence.Transient; @Entity public class Product implements ProductInterface { @TableGenerator( name = "PRODUCT_GEN_DETAILED", table = "ID_GEN", pkColumnName = "ID_GEN_NAME", valueColumnName = "ID_GEN_COUNT", initialValue = 100, allocationSize = 10) @Id @GeneratedValue(generator = "PRODUCT_GEN_DETAILED") private int id; private String name; private String description; private BigDecimal price; private boolean isCondiment; private String category; @Transient private Map<Product, Integer> condimentsInProduct = new LinkedHashMap<Product, Integer>(); public Product() { super(); } public Product(String name, String description, BigDecimal price, Map<Product, Integer> condimentsInProduct) { //TODO builder pattern super(); this.name = name; this.description = description; this.price = price; this.condimentsInProduct = condimentsInProduct; } // getters and setters }
CondimentDecorator.java
package product.domain; import java.math.BigDecimal; import java.util.Map; public class CondimentDecorator extends Product { private ProductInterface productInterface; public CondimentDecorator(ProductInterface beverage, String name, String description, BigDecimal price, Map<Product, Integer> condimentsInProduct) { super(name, description, price, condimentsInProduct); this.productInterface = beverage; } public String getName() { return this.productInterface.getName() + ", " + super.getName(); } @Override public BigDecimal getPrice() { return super.getPrice().add(this.productInterface.getPrice()); } @Override public String toString() { return this.getName() + " = " + this.getPrice(); } }
ProductInterface.java
package product.domain; import java.math.BigDecimal; public interface ProductInterface { String getName(); BigDecimal getPrice(); }
Builder Pattern
Kullanacagimiz metotlara fazla parametre gecmek yerine ShoppingCartData ‘yi gececegiz. Burada Builder Pattern’i kullanacagiz.
Kodumuz daha flexible/esnek olacak.
ShoppingCartData.java
package product.domain; import java.util.Map; import java.util.TreeMap; public class ShoppingCartData { private Map<Integer, TreeMap<Integer, Product>> shoppingCart; private Product product; private int orderIndexId; private int condimentId; private Map<Integer, Product> allCondimentsInShop; private ShoppingCartData(ShoppingCartDataBuilder builder) { this.shoppingCart = builder.shoppingCart; this.product = builder.product; this.orderIndexId = builder.orderIndexId; this.condimentId = builder.condimentId; this.allCondimentsInShop = builder.allCondimentsInShop; } public Map<Integer, TreeMap<Integer, Product>> getShoppingCart() { return shoppingCart; } public Product getProduct() { return product; } public int getOrderIndexId() { return orderIndexId; } public int getCondimentId() { return condimentId; } public Map<Integer, Product> getAllCondimentsInShop() { return allCondimentsInShop; } public static class ShoppingCartDataBuilder { private Map<Integer, TreeMap<Integer, Product>> shoppingCart; private Product product; private int orderIndexId; private int condimentId; private Map<Integer, Product> allCondimentsInShop; public ShoppingCartDataBuilder(Map<Integer, TreeMap<Integer, Product>> shoppingCart, Product product) { this.shoppingCart = shoppingCart; this.product = product; } public ShoppingCartDataBuilder shoppingCart(Map<Integer, TreeMap<Integer, Product>> shoppingCart) { this.shoppingCart = shoppingCart; return this; } public ShoppingCartDataBuilder product(Product product) { this.product = product; return this; } public ShoppingCartDataBuilder orderIndexId(int orderIndexId) { this.orderIndexId = orderIndexId; return this; } public ShoppingCartDataBuilder condimentId(int condimentId) { this.condimentId = condimentId; return this; } public ShoppingCartDataBuilder allCondimentsInShop(Map<Integer, Product> allCondimentsInShop) { this.allCondimentsInShop = allCondimentsInShop; return this; } public ShoppingCartData build() { return new ShoppingCartData(this); } } }
Web Layer / Product Crud Controller
ProductCRUDController.java
Bu sinifimizda urun ekleme / urun silme / urun guncelleme ve urun silme islemlerini gerceklestiriyoruz.
package product.controller; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import product.domain.Product; import product.service.ProductService; import product.validator.ProductValidator; import static product.utility.URLs.PRODUCT_ADD; import static product.utility.URLs.PRODUCT_EDIT; import static product.utility.URLs.PRODUCT_UPDATE; import static product.utility.URLs.PRODUCT_DELETE; import static product.utility.ViewURLs.PRODUCT_ADD_VIEW_REDIRECT; import static product.utility.ViewURLs.PRODUCT_ADD_VIEW; @Controller public class ProductCRUDController { @Autowired private ProductService productService; @Autowired private ProductValidator productValidator; @ModelAttribute("productCategories") public Map<String, String> prepareCategoryList() { Map<String, String> categories = new HashMap<String, String>(); categories.put("hot", "Hot Beverage"); categories.put("cold", "Cold Beverage"); categories.put("other", "Other"); return categories; } @RequestMapping(value = PRODUCT_ADD, method = RequestMethod.GET) public String getAddNewProductForm(@ModelAttribute("newProduct") Product newProduct, Model model) { model.addAttribute("allProducts", productService.getAllProductsAndCondiments()); return PRODUCT_ADD_VIEW; } @RequestMapping(value = PRODUCT_ADD, method = RequestMethod.POST) public String processAddNewProductForm(@ModelAttribute("newProduct") Product productToBeAdded, BindingResult bindingResult, Model model) { productValidator.validate(productToBeAdded, bindingResult); if (bindingResult.hasErrors()) { model.addAttribute("allProducts", productService.getAllProductsAndCondiments()); return PRODUCT_ADD_VIEW; } productService.addProduct(productToBeAdded); return PRODUCT_ADD_VIEW_REDIRECT; } @RequestMapping(value = PRODUCT_EDIT, method = RequestMethod.GET) public String editProduct(@RequestParam("id") int id, Model model) { model.addAttribute("newProduct", productService.getProductById(id)); model.addAttribute("allProducts", productService.getAllProductsAndCondiments()); model.addAttribute("update", "update"); return PRODUCT_ADD_VIEW; } @RequestMapping(value = PRODUCT_UPDATE, method = RequestMethod.POST) public String updatePerson(@ModelAttribute("newProduct") Product productToBeUpdated, BindingResult bindingResult, Model model) { productValidator.validate(productToBeUpdated, bindingResult); if (bindingResult.hasErrors()) { model.addAttribute("newProduct", productToBeUpdated); model.addAttribute("allProducts", productService.getAllProductsAndCondiments()); model.addAttribute("update", "update"); return PRODUCT_ADD_VIEW; } productService.updateProduct(productToBeUpdated); return PRODUCT_ADD_VIEW_REDIRECT; } @RequestMapping(value = PRODUCT_DELETE, method = RequestMethod.GET) public String deleteProduct(@ModelAttribute("newProduct") Product newProduct, @RequestParam("id") int id) { productService.deleteProduct(id); return PRODUCT_ADD_VIEW_REDIRECT; } }
Validator
ProductValidator sinifimizda org.springframework.validation.Validator arabirimini/interface uyguluyoruz.
name ve price alanlari icin validation ekleyelim , sart saglanmadigi takdirde error message ekleyelim.
ProductValidator.java
package product.validator; import java.math.BigDecimal; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; import product.domain.Product; @Component public class ProductValidator implements Validator { @Override public boolean supports(Class<?> clazz) { return false; } @Override public void validate(Object target, Errors errors) { Product product = (Product) target; ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name"); if (product.getPrice()==null || product.getPrice().compareTo(new BigDecimal(0))<0) { errors.rejectValue("price", "required.price"); } //TODO more validation } }
Web Layer / Product Menu Controller
Bu Controller sinifinda
- Urun listeleme (listAllProducts)
- Category ye gore filtreleme (listAllProductsByCategory)
- Urun detay (getProductDetail)
- Sepete urun ekleme (addProductToCart)
- Sepetten urun silme (deleteProductFromCart)
- Sepeti temizleme ( deleteAllProductFromCart )
- Ilgili urun icin eklenti/condiments ekleme (addNewCondimentToProduct)
- Ilgili urun icin eklenti/condiments silme (deleteCondimentFromProduct)
- Sepet detay (goToShoppingCart)
- Sepetten ilgili tum urunleri temizleme(deleteOrderFromCart)
ProductMenuController.java
package product.controller; import static product.utility.URLs.ALL; import static product.utility.URLs.CATEGORY; import static product.utility.URLs.DEFAULT_URL; import static product.utility.URLs.MENU; import static product.utility.URLs.ORDER_DELETE_FROM_CART; import static product.utility.URLs.PRODUCT_ADD_CONDIMENT; import static product.utility.URLs.PRODUCT_ADD_TO_CART; import static product.utility.URLs.PRODUCT_DELETE_ALL_CART; import static product.utility.URLs.PRODUCT_DELETE_CONDIMENT; import static product.utility.URLs.PRODUCT_DELETE_FROM_CART; import static product.utility.URLs.PRODUCT_DETAIL; import static product.utility.URLs.PRODUCT_SHOPPING_CART; import static product.utility.ViewURLs.PRODUCT_DETAIL_VIEW; import static product.utility.ViewURLs.PRODUCT_DETAIL_VIEW_REDIRECT; import static product.utility.ViewURLs.PRODUCT_LIST_VIEW; import static product.utility.ViewURLs.PRODUCT_SHOPPING_CART_VIEW; import static product.utility.ViewURLs.PRODUCT_SHOPPING_CART_VIEW_REDIRECT; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import product.domain.Product; import product.domain.ShoppingCartData; import product.service.ProductCartService; import product.service.ProductService; @Controller @RequestMapping(value = { MENU, DEFAULT_URL }) @SessionAttributes(value = { "product", "allCondimentsInShop", "shoppingCart" }) public class ProductMenuController { @Autowired private ProductService productService; @Autowired private ProductCartService productCartService; @ModelAttribute("shoppingCart") public void initializeShoppingCart(Model model) { Map<Integer, TreeMap<Integer, Product>> shoppingCart = new HashMap<Integer, TreeMap<Integer, Product>>(); model.addAttribute("shoppingCart", shoppingCart); } @RequestMapping(value = { ALL, DEFAULT_URL }, method = RequestMethod.GET) public String listAllProducts(Model model) { model.addAttribute("products", productService.getAllProducts()); return PRODUCT_LIST_VIEW; } @RequestMapping(value = CATEGORY, method = RequestMethod.GET) public String listAllProductsByCategory(@PathVariable("category") String productCategory, Model model) { model.addAttribute("products", productService.getProductsByCategory(productCategory)); return PRODUCT_LIST_VIEW; } @RequestMapping(value = PRODUCT_DETAIL, method = RequestMethod.GET) public String getProductDetail(@RequestParam("productId") int productId, Model model) { Map<Integer, Product> allCondimentsInShop = productService.getAllCondiments(); model.addAttribute("product", productService.getProductById(productId)); model.addAttribute("allCondimentsInShop", allCondimentsInShop); return PRODUCT_DETAIL_VIEW; } @RequestMapping(value = PRODUCT_ADD_TO_CART, method = RequestMethod.GET) public String addProductToCart(@ModelAttribute("product") Product product, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { ShoppingCartData data = new ShoppingCartData.ShoppingCartDataBuilder(shoppingCart, product).build(); productCartService.addProductToShoppingCart(data); return PRODUCT_DETAIL_VIEW_REDIRECT + product.getId(); } @RequestMapping(value = PRODUCT_DELETE_FROM_CART, method = RequestMethod.GET) public String deleteProductFromCart(@RequestParam("indexId") int productIndexIdInShoppingCart, @ModelAttribute("product") Product product, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { ShoppingCartData data = new ShoppingCartData.ShoppingCartDataBuilder(shoppingCart, product) .orderIndexId(productIndexIdInShoppingCart).build(); productCartService.deleteProductFromShoppingCart(data); return PRODUCT_DETAIL_VIEW_REDIRECT + product.getId(); } @RequestMapping(value = PRODUCT_DELETE_ALL_CART, method = RequestMethod.GET) public String deleteAllProductFromCart(@ModelAttribute("product") Product product, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { ShoppingCartData data = new ShoppingCartData.ShoppingCartDataBuilder(shoppingCart, product).build(); productCartService.deleteAllProductFromShoppingCartByProductId(data); return PRODUCT_DETAIL_VIEW_REDIRECT + product.getId(); } @RequestMapping(value = PRODUCT_ADD_CONDIMENT, method = RequestMethod.GET) public String addNewCondimentToProduct(@RequestParam("indexId") int orderIndexId, @RequestParam("condimentId") int condimentId, @ModelAttribute("product") Product product, @ModelAttribute("allCondimentsInShop") Map<Integer, Product> allCondimentsInShop, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { ShoppingCartData data = new ShoppingCartData.ShoppingCartDataBuilder(shoppingCart, product) .orderIndexId(orderIndexId).allCondimentsInShop(allCondimentsInShop).condimentId(condimentId).build(); productCartService.addCondimentToProductInShoppingCart(data); return PRODUCT_DETAIL_VIEW_REDIRECT + product.getId(); } @RequestMapping(value = PRODUCT_DELETE_CONDIMENT, method = RequestMethod.GET) public String deleteCondimentFromProduct(@RequestParam("indexId") int orderIndexId, @RequestParam("condimentId") int condimentId, @ModelAttribute("product") Product product, @ModelAttribute("allCondimentsInShop") Map<Integer, Product> allCondimentsInShop, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { ShoppingCartData data = new ShoppingCartData.ShoppingCartDataBuilder(shoppingCart, product) .orderIndexId(orderIndexId).allCondimentsInShop(allCondimentsInShop).condimentId(condimentId).build(); productCartService.deleteCondimentFromProductInShoppingCart(data); return PRODUCT_DETAIL_VIEW_REDIRECT + product.getId(); } @RequestMapping(value = PRODUCT_SHOPPING_CART, method = RequestMethod.GET) public String goToShoppingCart(@ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart, Model model, final RedirectAttributes redirectAttributes) { TreeMap<Integer, BigDecimal> calculatedPrices = productCartService .calculateProductsSumByIdInShoppingCart(shoppingCart); BigDecimal totalAll = productCartService.calculateProductsSumAllInShoppingCart(calculatedPrices); Map<Integer, Product> products = new HashMap<Integer, Product>(); for (Product product : productService.getAllProducts()) { products.put(product.getId(), product); } model.addAttribute("products", products); model.addAttribute("calculatedPrices", calculatedPrices); model.addAttribute("totalAll", totalAll); model.addAttribute("reducedPrice", productCartService.calculateDiscount(shoppingCart)); return PRODUCT_SHOPPING_CART_VIEW; } @RequestMapping(value = ORDER_DELETE_FROM_CART, method = RequestMethod.GET) public String deleteOrderFromCart(@RequestParam("productId") int productId, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { shoppingCart.remove(productId); return PRODUCT_SHOPPING_CART_VIEW_REDIRECT; } }
Web Layer /Payment Controller
Bu Controller sinifimizda ;
- Odeme form sayfasi
- Odeme islemi
- Islem sonucu ve status’u tamamlama islemleri yapilmaktadir.
PaymentController.java
package product.controller; import static product.utility.URLs.ORDER_PAYMENT; import static product.utility.URLs.ORDER_PAYMENT_CONFIRM; import static product.utility.URLs.ORDER_PAYMENT_SUCCESS; import static product.utility.ViewURLs.ORDER_PAYMENT_FORM_VIEW; import static product.utility.ViewURLs.ORDER_PAYMENT_VIEW_SUCCESS; import static product.utility.ViewURLs.ORDER_PAYMENT_VIEW_SUCCESS_REDIRECT; import java.math.BigDecimal; import java.util.Map; import java.util.TreeMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.support.SessionStatus; import product.domain.Product; import product.domain.order.Customer; import product.domain.order.Order; import product.domain.order.PaymentFormData; import product.service.OrderService; import product.service.ProductCartService; @Controller @SessionAttributes(value = { "shoppingCart" }) public class PaymentController { @Autowired private ProductCartService productCartService; @Autowired private OrderService orderService; @RequestMapping(value = ORDER_PAYMENT, method = RequestMethod.POST) public String payment(@ModelAttribute("paymentFormData") PaymentFormData paymentFormData, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart, Model model) { BigDecimal calculatedAmount = productCartService.calculateDiscount(shoppingCart); model.addAttribute("calculatedAmount", calculatedAmount); model.addAttribute("paymentFormData", paymentFormData); return ORDER_PAYMENT_FORM_VIEW; } @RequestMapping(value = ORDER_PAYMENT_CONFIRM, method = RequestMethod.POST) public String paymentConfirm(@ModelAttribute("paymentFormData") PaymentFormData paymentFormData, @ModelAttribute("shoppingCart") Map<Integer, TreeMap<Integer, Product>> shoppingCart) { Customer customer = new Customer(paymentFormData.getCustomerName()); Order order = new Order(); BigDecimal calculatedAmount = productCartService.calculateDiscount(shoppingCart); order.setAmount(calculatedAmount); order.setCustomer(customer); orderService.insertOrder(order); return ORDER_PAYMENT_VIEW_SUCCESS_REDIRECT; } @RequestMapping(value = ORDER_PAYMENT_SUCCESS, method = RequestMethod.GET) public String paymentSuccess(SessionStatus status) { status.setComplete(); return ORDER_PAYMENT_VIEW_SUCCESS; } }
Web Layer /Order List Controller
Bu Controller sinifinda satilan/tamamlanan siparis bilgileri yer almaktadir.
OrderListController.java
package product.controller; import static product.utility.URLs.ORDER_LIST; import static product.utility.ViewURLs.ORDER_LIST_VIEW; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import product.service.OrderService; @Controller public class OrderListController { @Autowired private OrderService orderService; @RequestMapping(value = ORDER_LIST, method = RequestMethod.GET) public String getCustomerOrderList(Model model, @RequestParam(value = "groupBy", required = false) String groupByCustomerName) { model.addAttribute("ordersTotals", orderService.getOrdersTotalAmount()); model.addAttribute("allCustomerOrders", orderService.getOrderList()); if (groupByCustomerName != null && groupByCustomerName.equals("customerName")) { model.addAttribute("ordersAmountByCustomerName", orderService.getOrdersTotalAmountByCustomerName()); } return ORDER_LIST_VIEW; } }
Customer/ Order Domain
Order ve Customer siniflarimizi tanimlayalim.
Customer.java
package product.domain.order; import java.util.List; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.TableGenerator; @Entity public class Customer { @TableGenerator( name = "CUSTOMER_GEN_DETAILED", table = "CUSTOMER_ID_GEN", pkColumnName = "ID_GEN_NAME", valueColumnName = "ID_GEN_COUNT", initialValue = 1, allocationSize = 10) @Id @GeneratedValue(generator = "CUSTOMER_GEN_DETAILED") private int id; private String customerName; @OneToMany(mappedBy = "customer") private List<Order> orders; //getters and setters }
Order.java
package product.domain.order; import java.math.BigDecimal; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.TableGenerator; @Entity(name = "CustomerOrder") public class Order { @TableGenerator( name = "ORDER_GEN_DETAILED", table = "ORDER_ID_GEN", pkColumnName = "ID_GEN_NAME", valueColumnName = "ID_GEN_COUNT", initialValue = 1, allocationSize = 10) @Id @GeneratedValue(generator = "ORDER_GEN_DETAILED") private int id; private BigDecimal amount; @ManyToOne(cascade=CascadeType.ALL) private Customer customer; //getters and setters }
Payment Form Data Domain
PaymentFormData.java
Odeme formunda kullanacagimiz sinifimizi olusturalim ;
package product.domain.order; public class PaymentFormData { private String customerName; private String cardNumber; private int month; private int year; private String cvv; //getters and setters }
Service Layer
OrderService arabiriminde ;
- Siparis kaydi ekleme (insertOrder)
- Tum siparislerin getirilmesi ( getOrderList)
- Tum siparisler icin toplam amount bilgisi getirilmesi ( getOrdersTotalAmount )
- Musteriye gore farkli siparisler icin toplam amount bilgisi getirilmesi
OrderService.java
package product.service; import java.math.BigDecimal; import java.util.List; import product.domain.order.Order; public interface OrderService { public void insertOrder(Order order); public List<Order> getOrderList(); public BigDecimal getOrdersTotalAmount(); public List<Object[]> getOrdersTotalAmountByCustomerName(); }
OrderServiceImpl.java
package product.service; import java.math.BigDecimal; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import product.dao.OrderDAO; import product.domain.order.Order; @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderDAO orderDAOImpl; @Transactional public void insertOrder(Order order) { orderDAOImpl.insertOrder(order); } @Override @Transactional public List<Order> getOrderList() { return orderDAOImpl.getOrderList(); } @Override @Transactional public BigDecimal getOrdersTotalAmount() { return orderDAOImpl.getOrdersTotalAmount(); } @Override @Transactional public List<Object[]> getOrdersTotalAmountByCustomerName() { return orderDAOImpl.getOrdersTotalAmountByCustomerName(); } }
ProductService.java
- Tum Urunleri listeleme
- Tum Urunleri ve Condimentsleri listeleme
- Tum Condimentleri listeleme
- Urunu id ye gore getirme
- Category’e gore urunleri getirme
- Urun ekleme
- Urun silme
- Urun guncelleme islemleri yapilmaktadir.
package product.service; import java.util.List; import java.util.Map; import product.domain.Product; public interface ProductService { public List<Product> getAllProducts(); public List<Product> getAllProductsAndCondiments(); public Map<Integer, Product> getAllCondiments(); public Product getProductById(int id); public List<Product> getProductsByCategory(String category); public void addProduct(Product product); public void deleteProduct(int id); public void updateProduct(Product product); }
ProductServiceImpl.java
package product.service; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import product.dao.ProductRepositoryDAO; import product.domain.Product; @Service public class ProductServiceImpl implements ProductService { @Autowired private ProductRepositoryDAO productRepository; @Transactional @Override public List<Product> getAllProductsAndCondiments() { return productRepository.getAllProductsAndCondiments(); } @Transactional @Override public List<Product> getAllProducts() { return productRepository.getAllProducts(); } @Transactional @Override public Map<Integer, Product> getAllCondiments() { List<Product> results = productRepository.getAllCondiments(); Map<Integer, Product> map = new HashMap<Integer, Product>(); for (Product product : results) { map.put(product.getId(), product); } return map; } @Transactional @Override public Product getProductById(int productID) { return productRepository.getProductById(productID); } @Transactional @Override public List<Product> getProductsByCategory(String category) { return productRepository.getProductsByCategory(category); } @Transactional @Override public void addProduct(Product product) { productRepository.addProduct(product); } @Override @Transactional public void deleteProduct(int id) { productRepository.deleteProduct(id); } @Override @Transactional public void updateProduct(Product product) { productRepository.updateProduct(product); } }
ProductCartService.java
- Shopping Cart’a product/urun ekleme , urun silme
- Condiment/eklenti ekleme/silme
- Discount/indirimleri ve amount hesaplama islemleri yapilmaktadir.
package product.service; import java.math.BigDecimal; import java.util.Map; import java.util.TreeMap; import product.domain.Product; import product.domain.ShoppingCartData; public interface ProductCartService { public void addProductToShoppingCart(ShoppingCartData data); public void deleteProductFromShoppingCart(ShoppingCartData data); public void deleteAllProductFromShoppingCartByProductId(ShoppingCartData data); public void addCondimentToProductInShoppingCart(ShoppingCartData data); public void deleteCondimentFromProductInShoppingCart(ShoppingCartData data); public TreeMap<Integer, BigDecimal> calculateProductsSumByIdInShoppingCart(Map<Integer, TreeMap<Integer, Product>> shoppingCart); public BigDecimal calculateProductsSumAllInShoppingCart(TreeMap<Integer, BigDecimal> sumByProductId); public BigDecimal calculateDiscount(Map<Integer, TreeMap<Integer, Product>> shoppingCart); }
ProductCartServiceImpl.java
package product.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.springframework.stereotype.Service; import product.domain.CondimentDecorator; import product.domain.Product; import product.domain.ShoppingCartData; @Service public class ProductCartServiceImpl implements ProductCartService { @Override public void addProductToShoppingCart(ShoppingCartData data) { TreeMap<Integer, Product> productMap = data.getShoppingCart().get(data.getProduct().getId()); if (productMap == null) { productMap = new TreeMap<Integer, Product>(); } int count = 0; if (productMap.size() > 0) { count = productMap.lastKey(); } productMap.put(++count, data.getProduct()); data.getShoppingCart().put(data.getProduct().getId(), productMap); } public TreeMap<Integer, BigDecimal> calculateProductsSumByIdInShoppingCart( Map<Integer, TreeMap<Integer, Product>> shoppingCart) { TreeMap<Integer, BigDecimal> sumByProductId = new TreeMap<Integer, BigDecimal>(); for (Map.Entry<Integer, TreeMap<Integer, Product>> productsByIds : shoppingCart.entrySet()) { BigDecimal totalPriceByProductId = new BigDecimal(0); TreeMap<Integer, Product> mapByProductId = productsByIds.getValue(); for (Map.Entry<Integer, Product> entry : mapByProductId.entrySet()) { totalPriceByProductId = totalPriceByProductId.add(entry.getValue().getPrice()); sumByProductId.put(productsByIds.getKey(), totalPriceByProductId); } } for (Map.Entry<Integer, BigDecimal> abc : sumByProductId.entrySet()) { System.out.println("product id : " + abc.getKey() + " total : " + abc.getValue()); } return sumByProductId; } public BigDecimal calculateProductsSumAllInShoppingCart(TreeMap<Integer, BigDecimal> sumByProductId) { BigDecimal total = new BigDecimal(0); for (Map.Entry<Integer, BigDecimal> entry : sumByProductId.entrySet()) { total = total.add(entry.getValue()); } return total; } @Override public BigDecimal calculateDiscount(Map<Integer, TreeMap<Integer, Product>> shoppingCart) { List<BigDecimal> priceList = new ArrayList<BigDecimal>(); BigDecimal totalPrice = new BigDecimal(0); for (Map.Entry<Integer, TreeMap<Integer, Product>> productsByIds : shoppingCart.entrySet()) { TreeMap<Integer, Product> mapByProductId = productsByIds.getValue(); for (Map.Entry<Integer, Product> entry : mapByProductId.entrySet()) { Product product = entry.getValue(); totalPrice = totalPrice.add(product.getPrice()); priceList.add(product.getPrice()); } } BigDecimal reducedPriceByProductCount = totalPrice; // default total // price //TODO , make it dynamic by properties if (priceList.size() >= 3) { BigDecimal minimumPriceInShoppingCart = Collections.min(priceList); reducedPriceByProductCount = totalPrice.subtract(minimumPriceInShoppingCart); } BigDecimal reducedPriceByPercentage = totalPrice; // detault total price if (totalPrice.compareTo(new BigDecimal(12)) > 0) { BigDecimal remainder = totalPrice.divide(new BigDecimal(4)); reducedPriceByPercentage = totalPrice.subtract(remainder); } if (reducedPriceByPercentage.compareTo(reducedPriceByProductCount) < 0) { return reducedPriceByPercentage; } else { return reducedPriceByProductCount; } } @Override public void deleteProductFromShoppingCart(ShoppingCartData data) { TreeMap<Integer, Product> productMap = data.getShoppingCart().get(data.getProduct().getId()); productMap.remove(data.getOrderIndexId()); } @Override public void deleteAllProductFromShoppingCartByProductId(ShoppingCartData data) { data.getShoppingCart().remove(data.getProduct().getId()); } public void addCondimentToProductInShoppingCart(ShoppingCartData data) { TreeMap<Integer, Product> productMap = data.getShoppingCart().get(data.getProduct().getId()); Product selectedProductForCondimentProcess = productMap.get(data.getOrderIndexId()); Product condiment = data.getAllCondimentsInShop().get(data.getCondimentId()); selectedProductForCondimentProcess = new CondimentDecorator(selectedProductForCondimentProcess, condiment.getName(), condiment.getDescription(), condiment.getPrice(), selectedProductForCondimentProcess.getCondimentsInProduct()); Map<Product, Integer> map = selectedProductForCondimentProcess.getCondimentsInProduct(); Integer count = map.get(condiment); if (count == null) { count = 0; } selectedProductForCondimentProcess.getCondimentsInProduct().put(condiment, ++count); productMap.put(data.getOrderIndexId(), selectedProductForCondimentProcess); } @Override public void deleteCondimentFromProductInShoppingCart(ShoppingCartData data) { TreeMap<Integer, Product> productMap = data.getShoppingCart().get(data.getProduct().getId()); Product selectedProductForCondimentProcess = productMap.get(data.getOrderIndexId()); Product condiment = data.getAllCondimentsInShop().get(data.getCondimentId()); Map<Product, Integer> map = selectedProductForCondimentProcess.getCondimentsInProduct(); Integer count = map.get(condiment); selectedProductForCondimentProcess = new CondimentDecorator(selectedProductForCondimentProcess, condiment.getName(), condiment.getDescription(), (condiment.getPrice().multiply(new BigDecimal(count)).negate()), selectedProductForCondimentProcess.getCondimentsInProduct()); selectedProductForCondimentProcess.getCondimentsInProduct().remove(condiment); productMap.put(data.getOrderIndexId(), selectedProductForCondimentProcess); } }
DAO Layer
OrderDAO.java
package product.dao; import java.math.BigDecimal; import java.util.List; import product.domain.order.Order; public interface OrderDAO { public void insertOrder(Order order); public List<Order> getOrderList(); public BigDecimal getOrdersTotalAmount(); public List<Object[]> getOrdersTotalAmountByCustomerName(); }
OrderDAOImpl.java
package product.dao; import java.math.BigDecimal; import java.util.List; import javax.persistence.TypedQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import product.domain.order.Order; @Repository public class OrderDAOImpl implements OrderDAO { @Autowired private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } private Session getCurrentSession() { return sessionFactory.getCurrentSession(); } @Override public void insertOrder(Order order) { Session session = getCurrentSession(); session.persist(order); } @Override public List<Order> getOrderList() { Session session = getCurrentSession(); TypedQuery<Order> query = session.createQuery("from CustomerOrder", Order.class); return query.getResultList(); } @Override public BigDecimal getOrdersTotalAmount() { Session session = getCurrentSession(); TypedQuery<BigDecimal> query = session.createQuery("Select sum(o.amount) from CustomerOrder o", BigDecimal.class); return query.getSingleResult(); } public List<Object[]> getOrdersTotalAmountByCustomerName() { Session session = getCurrentSession(); TypedQuery<Object[]> query = session.createQuery( "Select o.customer.customerName , sum(o.amount) from CustomerOrder o group by o.customer.customerName", Object[].class); return query.getResultList(); } }
ProductRepositoryDAO.java
package product.dao; import java.util.List; import product.domain.Product; public interface ProductRepositoryDAO { public List<Product> getAllProducts(); public List<Product> getAllCondiments(); public List<Product> getAllProductsAndCondiments(); public Product getProductById(int productID); public List<Product> getProductsByCategory(String category); public void addProduct(Product product); public void deleteProduct(int id); public void updateProduct(Product product); }
ProductRepositoryDAOImpl.java
package product.dao; import java.util.List; import javax.persistence.TypedQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import product.domain.Product; @Repository public class ProductRepositoryDAOImpl implements ProductRepositoryDAO { @Autowired private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } private Session getCurrentSession() { return sessionFactory.getCurrentSession(); } @Override public List<Product> getAllProductsAndCondiments() { Session session = getCurrentSession(); TypedQuery<Product> query = session.createQuery("from Product", Product.class); return query.getResultList(); } @Override public List<Product> getAllProducts() { Session session = getCurrentSession(); TypedQuery<Product> query = session.createQuery("from Product where isCondiment = false", Product.class); return query.getResultList(); } @Override public List<Product> getAllCondiments() { Session session = getCurrentSession(); TypedQuery<Product> query = session.createQuery("from Product where isCondiment = true", Product.class); return query.getResultList(); } @Override public Product getProductById(int id) { Session session = getCurrentSession(); Product product = session.get(Product.class, id); return product; } @Override public List<Product> getProductsByCategory(String category) { Session session = getCurrentSession(); TypedQuery<Product> query = session.createQuery("from Product p where p.category =:category", Product.class) .setParameter("category", category); return query.getResultList(); } @Override public void addProduct(Product product) { Session session = getCurrentSession(); session.persist(product); } @Override public void deleteProduct(int id) { Session session = getCurrentSession(); Product p = (Product) session.get(Product.class, id); System.out.println(p); if (p != null) { session.delete(p); } } @Override public void updateProduct(Product product) { Session session = getCurrentSession(); session.update(product); } }
Utility
Projemizde URL adreslerini ve View’leri toplu olarak siniflarda tanimlayabiliriz.
URLs.java
package product.utility; public interface URLs { public static final String MENU = "/menu"; public static final String ALL = "/all"; public static final String CATEGORY = "/{category}"; // URI template public static final String PRODUCT_DETAIL = "/product.detail"; public static final String PRODUCT_ADD_TO_CART = "/product.add.to.cart"; public static final String PRODUCT_DELETE_FROM_CART = "/product.delete.from.cart"; public static final String PRODUCT_DELETE_ALL_CART = "/product.delete.all.cart"; public static final String PRODUCT_ADD_CONDIMENT = "/product.add.condiment"; public static final String PRODUCT_DELETE_CONDIMENT = "/product.delete.condiment"; public static final String PRODUCT_SHOPPING_CART = "/product.shopping.cart"; public static final String ORDER_DELETE_FROM_CART = "/order.delete.from.cart"; public static final String DEFAULT_URL = "/"; // CRUD menu public static final String ADMIN_LOGIN ="/login.admin"; public static final String PRODUCT_ADD = "/product.add"; public static final String PRODUCT_EDIT = "/product.edit"; public static final String PRODUCT_UPDATE = "/product.update"; public static final String PRODUCT_DELETE = "/product.delete"; //PAYMENT public static final String ORDER_PAYMENT = "/order.payment"; public static final String ORDER_PAYMENT_CONFIRM = "/order.payment.confirm"; public static final String ORDER_PAYMENT_SUCCESS ="/order.payment.success"; public static final String ORDER_LIST ="/order.list"; }
ViewURLs.java
package product.utility; public interface ViewURLs { public static final String PRODUCT_LIST_VIEW = "product.views/productList"; public static final String PRODUCT_DETAIL_VIEW = "product.views/productDetail"; public static final String PRODUCT_DETAIL_VIEW_REDIRECT = "redirect:/menu/product.detail?productId="; public static final String PRODUCT_SHOPPING_CART_VIEW = "product.views/shoppingCart"; public static final String PRODUCT_SHOPPING_CART_VIEW_REDIRECT = "redirect:/menu/product.shopping.cart"; public static final String PRODUCT_ADD_VIEW="product.views/addProduct"; public static final String PRODUCT_ADD_VIEW_REDIRECT="redirect:/product.add"; public static final String ORDER_PAYMENT_FORM_VIEW = "product.views/paymentForm"; public static final String ORDER_PAYMENT_VIEW_SUCCESS ="product.views/paymentSuccess"; public static final String ORDER_PAYMENT_VIEW_SUCCESS_REDIRECT ="redirect:/order.payment.success"; public static final String ORDER_LIST_VIEW="product.views/orderList"; }
View Layer
View Layer’da JSP sayfalari kullanildi.
Ilerleyen zamanlarda guncelleme yapip , bu kisimlar icin de onemli noktalari aciklamalari ekleyecegim.
Simdilik icerikleri proje icerisinde bulabilirsiniz.
Log4j
log4j.properties
#all logs log4j.rootLogger=INFO, file log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File= ${catalina.home}/logs/all.txt log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n log4j.logger.auditLogger=INFO, auditLogger log4j.appender.auditLogger=org.apache.log4j.RollingFileAppender log4j.appender.auditLogger.File= ${catalina.home}/logs/audit.txt log4j.appender.auditLogger.layout=org.apache.log4j.PatternLayout log4j.appender.auditLogger.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c : %m%n log4j.logger.admin=INFO, admin log4j.appender.admin=org.apache.log4j.RollingFileAppender log4j.appender.admin.File= ${catalina.home}/logs/admin.txt log4j.appender.admin.layout=org.apache.log4j.PatternLayout log4j.appender.admin.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c : %m%n
Run Application
Projemizi calistiralim ;
Projemiz sorunsuzca ayaga kalkti ve sql scriptleri ile ekledigimiz urunleri gormekteyiz.
Admin iconuna tiklayalim , CRUD menusune gidelim.
Bu menude Urun/Condiment(Eklenti) ekleme , silme , guncelleme islemlerini yapabiliriz.
Turkiye bayragina tiklarsak tum mesajlar TR olacaktir.
Ev iconuna tiklayip tekradan urunler sayfasina gelebiliriz , sonrasinda bir urunun detayina girerek ayni urunden birden fazla ekleyebilir , diledigimize istedigimiz eklentiyi istedigimiz sayida ekleyebiliriz.
Sepetim butonuna tikladigimizda , Sepete ekledigimiz urunleri toplu olarak gorebiliriz.
Burada urun fiyati ve ilgili senaryolara gore indirimli fiyati gorebiliriz.
Odeme sayfasina gidelim ;
Son olarak Siparis Listelerini inceleyelim ;
Yazimi burada sonlandiriyorum.
Herkese bol Javali gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer
Leave a Reply