版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
學號財經(jīng)學院畢業(yè)論文(設計)基于JAVA的網(wǎng)上商城設計與實現(xiàn)系部名稱:信息工程系專業(yè)名稱:計算機科學與技術學生姓名:指導教師:講師緒論研究的背景和意義研究的背景在衣食等購買方面,傳統(tǒng)的方式是我們需要花費時間到固定的地方挑選,假設購買的東西多還需要額外的花費去運輸。但是隨著中國經(jīng)濟的快速發(fā)展,人們對物質(zhì)生活要求的提升,工作時間的不充足,購買量偏大這些問題往往會使我們感到厭煩。如何改善人們的購物體驗,如何使商家與顧客實現(xiàn)共贏,人們一直在嘗試各種辦法解決這個問題。隨著互聯(lián)網(wǎng)技術的發(fā)展,網(wǎng)絡與人們的日常生活也產(chǎn)生了千絲萬縷的關系。信息技術也改變了人們的思維方式,現(xiàn)在越來越多的人通過互聯(lián)網(wǎng)來完成自己想做的事情。隨著數(shù)據(jù)庫,計算機硬件,存儲技術的發(fā)展,信息技術已經(jīng)覆蓋到日常生活的各個方面,現(xiàn)在人們已經(jīng)離不開互聯(lián)網(wǎng)了。網(wǎng)上購物商城就是在這種大趨勢的推動下產(chǎn)生的。研究的意義在衣食等方面網(wǎng)上購物商城充當著一個重要的角色,在以往我們需要花費時間去挑選去到固定的地方去買。而現(xiàn)在我們只需要動動我們的手指很多東西就可以送貨上門??梢宰C明商城很火爆的一個列子是天貓雙十一。可以說是開辟了網(wǎng)上購物的一個春天,成交量超過千億,可以說明現(xiàn)在互聯(lián)網(wǎng)購物商城方面的一個發(fā)展趨勢。研究內(nèi)容本系統(tǒng)采用SSM搭建的分布式項目,使用Maven管理Jar使用Git作為版本的管理工具,由此將項目分為如下幾個模塊:1)后臺管理:包括管理員對商品的增刪改查,對商品規(guī)格參數(shù)的增刪改查。2)主頁展示:類似京東的主頁面,讓商品分類目展示。論文組織結(jié)構:闡述了商城項目研究的背景與意義以及論文的組織結(jié)構:介紹了在商城項目中用到的JavaWEB技術以及開發(fā)工具以及Eclipse中比較好的插件的用法。:介紹了該系統(tǒng)的基本功能需求以及業(yè)務流程:實現(xiàn)對ssm框架的整合。對商城主要功能模塊的時間:對網(wǎng)上商城的前臺后臺進行一些數(shù)據(jù)測試保證其健壯性,穩(wěn)定性。:總結(jié)商城開發(fā)過程中用到的問題,分析優(yōu)勢與不足,明確下一步的工作內(nèi)容。 商城系統(tǒng)開發(fā)技術及工具介紹商城開發(fā)的核心技術Jsonp簡介跨域的基本概念:不同服務器或者同一個服務器不同的端口號他們之間進行通信這就叫做跨域在商城項目中單點登錄要實現(xiàn)在一個地方登錄其他地方不用再重新登錄,在這個地方需要用到跨域,在JSP頁面使用跨域要用到Jsonp。Jsonp:Jsonp就是JSON的特殊使用法.因為Ajax無法接收到跨域的Json類型數(shù)據(jù),Jsonp讓跨域時返回的是一個腳本文件.腳本文件中包含了,回調(diào)函數(shù)及JSON數(shù)據(jù).JSONP的使用步驟:客戶端需要重點設置以下三個屬性:1)dataType:’jsonp’,響應結(jié)果類型2)jsonp:’callback:,請求時傳遞回調(diào)方法名的參數(shù)名3)jsonpCallback:’abc,傳遞過去的回調(diào)方法名代碼示例如下:$.ajax({ url:'http://localhost:8081/demo', dataType:'jsonp', jsonp:'callback', jsonpCallback:'abc', type:'POST', success:function(data){ alert(data.a+""+"匿名方式"+data.b); }});服務器端使用的是由Spring封裝的MappingJacksonValue它返回jsonp需要的數(shù)據(jù)格式。他要注意的是幾個屬性produces:string[],設置響應頭中Content-Type,響應內(nèi)容類型.代碼示例如下:@RequestMapping(value="demo",produces={MediaType.APPLICATION_JSON_UTF8_VALUE})@ResponseBodypublicMappingJacksonValueshow(Stringcallback){ Map<String,String>map=newHashMap<>(); map.put("a","a1"); map.put("b","b1"); MappingJacksonValuemjv=newMappingJacksonValue(map); mjv.setJsonpFunction(callback); returnmjv;HttpClient簡介分布式項目中不同子項目之間進行信息傳輸需要跨域,而HttpClient是用Java代碼的方式進行的跨域信息交流,下面介紹一下HttpClient。HTTP協(xié)議應該是互聯(lián)網(wǎng)中最重要的協(xié)議。持續(xù)增長的WEB服務、互聯(lián)網(wǎng)的家用電器等都在繼承并拓展著Http協(xié)議,向著瀏覽器之外的方向發(fā)展。雖然JDK中的J包中提供了一些基本的方法,通過Http協(xié)議來訪問網(wǎng)絡資源,但是大多數(shù)場景下,它都不夠靈活和強大。HttpCilent致力于填補這個空白,它可以提供有效的、最新的、功能豐富的包來實現(xiàn)Http客戶端。為了拓展,Httpclient即支持基本的Http協(xié)議,還支持Http-aware客戶端程序,如WEB瀏覽器,WebServer客戶端,以及利用OR拓展Http協(xié)議的分布式系統(tǒng)。1)HttpClient的范圍/特性是一個基于Httpcore的客戶端Http傳輸類庫基于傳統(tǒng)的(阻塞)IO內(nèi)容無關2)HttpClient不能做的事情HttpClient不是瀏覽器,它是一個客戶端HTTP協(xié)議傳輸類庫。HttpClient被用來發(fā)送和接受HTTP消息。HttpClient不會處理HTTP消息的內(nèi)容,不會進行JavaScript解析,不會關心contenttype,如果沒有明確設置,HttpClientT也不會對請求進行格式化、重定向URL,或者其他任何和Http消息傳輸相關的功能。代碼示例如下:POST請求 CloseableHttpClienthttpClient=HttpClients.createDefault(); HttpPostpost=newHttpPost("http://localhost:8081/demo1"); List<NameValuePair>params=newArrayList<NameValuePair>(); params.add(newBasicNameValuePair("name","李四")); params.add(newBasicNameValuePair("age","15")); post.setEntity(newUrlEncodedFormEntity(params,"utf-8")); CloseableHttpResponseresponse=httpClient.execute(post); Stringresult=EntityUtils.toString(response.getEntity()); response.close(); httpClient.close();GET請求:publicvoiddoGetWithParam()throwsException{ CloseableHttpClienthttpClient=HttpClients.createDefault(); URIBuilderuriBuilder=newURIBuilder("/web"); uriBuilder.addParameter("query","花千骨"); HttpGetget=newHttpGet(uriBuilder.build()); CloseableHttpResponseresponse=httpClient.execute(get); intstatusCode=response.getStatusLine().getStatusCode(); HttpEntityentity=response.getEntity(); Stringstring=EntityUtils.toString(entity,"utf-8"); response.close(); httpClient.close();}Cookie簡介Cookie概念:由服務器端產(chǎn)生,存放于客戶端瀏覽器的文本文件。Cookie原理:1)在服務器端實例化Cookie對象,里面只能存放字符串內(nèi)容(Cookie盡量不要存放中文)。2)設置Cookie的有效時間和作用域和有效路徑。3)伴隨重定向,隨著響應對象響應給客戶端瀏覽器。4)瀏覽器接收到Cookie內(nèi)容進行I/O操作,把Cookie存放與本地某個Cookie特定文件夾中。5)當用戶在次發(fā)送請求時,只要能獲取到某個或某些Cookie,會由瀏覽器幫助自動攜帶Cookie發(fā)送給服務端。服務器端示例代碼如下:Cookiec=newCookie("test","123");c.setMaxAge(10);c.setDomain(".");c.setPath("/cookie/page");res.addCookie(c);res.sendRedirect("page/index.jsp");客戶端代碼示例如下:<%Cookie[]cs=request.getCookies();if(cs!=null){ for(Cookiec:cs){ out.println(c.getName()+""+c.getValue()+"<br/>"); }}%>Session簡介Session是什么?由服務器端產(chǎn)生,存放于客戶端瀏覽器的文本文件。Session原理:1)在服務器端實例化Cookie對象,里面只能存放字符串內(nèi)容(Cookie盡量不要存放中文)。2)設置Cookie的有效時間和作用域和有效路徑。3)伴隨重定向,隨著響應對象響應給客戶端瀏覽器。4)瀏覽器接收到Cookie內(nèi)容進行I/O操作,把Cookie存放與本地某個Cookie特定文件夾中。5)當用戶在次發(fā)送請求時,只要能獲取到某個或某些Cookie,會由瀏覽器幫助自動攜帶Cookie發(fā)送給服務端。Solr簡介Solr介紹1)作用:一個搜索引擎。2)SOLR實際是一個WEB項目。3)優(yōu)點:搜索內(nèi)容高亮。對搜索關鍵字的突出顯示。搜索引擎方案:目前在國內(nèi)希望實現(xiàn)全文搜索常用解決方案。1)使用Baidu,Google提供的API2)使用基于Apache提供的Lucene搜索引擎實現(xiàn)。Solr運行原理:Solr實際上是基于lucceen開發(fā)的,需要通過Solr對外提供的接口,訪問Solr項目.Solr接收請求,交由SolrRequestHandler,處理請求.拆分請求內(nèi)容為n多個詞條(一句話拆分成多段).根據(jù)詞條內(nèi)容,索引整個Solr中內(nèi)容,最終相應給用戶一個XML格式的結(jié)果,也可以是備用結(jié)果。索引介紹:1)查詢時,從頭查詢到結(jié)果一行一行的查詢過程叫做順序查詢。2)索引:建立內(nèi)容和索引內(nèi)容之間關系,通過找到索引內(nèi)容快速定位到具體內(nèi)容的過程就是索引查詢(新華字典目錄.)。3)solr基于反向索引進行查詢的.建立索引和內(nèi)容之間關系,通過索引查找內(nèi)容的過程稱為反向索引。SSM框架技術框架技術概述框架是一種通用的半成品的軟件,SSM用了MVC的設計模式可以使程序易維護擴展,使程序員之間的分工比較明確,使業(yè)務邏輯與視圖進行分離,簡化了程序員的開發(fā)提高了工作效率,如圖2-1就是框架技術在MVC三層模型所代表的角色。Servlet(C)Servlet(C)用戶JSP(V)Service(業(yè)務邏輯處理)DAODataBase從上到下:傳遞的是參數(shù)封裝的對象Mybatis從下到上:從數(shù)據(jù)庫中取出的結(jié)果封裝的對象SpringMVCSpring圖2-1框架在MVC中的角色SpringMVC框架Springmvc運行流程圖如圖2-2圖2-2SpringMVC執(zhí)行時序圖Springmvc運行原理:在編程中都是以spring-webmvc.jar形式存在.SpringMVC是基于front設計模式研發(fā)出來的必須有入口地址,地址是DispatcherServlet。DispatcherServlet也是一個Servlet,在SpringMVC中ServletAPI被完整的支持.由于是一個MVC框架,所以核心是控制器.大部分執(zhí)行流程都是在控制器前后完成的。具體執(zhí)行流程為:當用戶發(fā)送請求后被DispatcherSevlet進行分發(fā),然后轉(zhuǎn)交給HandlerMapping進行驗證格式是否合法,如果不合法報異常,如果合法向下傳遞交給HandlerAdapter準備調(diào)用某個Controller,Controller在進入之前一般都需要執(zhí)行HandlerInterceptor攔截器的preHandle()方法,判斷是否可以調(diào)用Controller.如果可以調(diào)用才能進入Controller,當Controller執(zhí)行完成后再次進入攔截的postHandle驗證傳遞內(nèi)容是否合法,如果合法交給ViewResovler視圖解析器調(diào)用具體的View視圖資源.調(diào)用成功后再次進入攔截器的afterCompletion做最后驗證,如果一切正確,響應給客戶端.到此,SpirngMVC執(zhí)行結(jié)束.Mybatis框架Mybatis運行流程圖如圖2-3圖2-3MYBATIS的執(zhí)行流程圖2-3Mybatis的執(zhí)行流程Mybatis是持久層框架,內(nèi)部封裝的JDBC,不依賴于SERVLET容器在測試階段使用比較方便。它的運行原理如下:運行原理就是程序執(zhí)行過程,平時編寫代碼時只需要把配置文件轉(zhuǎn)換為流后給交SqlSessionFactoryBuilder就會產(chǎn)生SqlSessionFactory,但實際上底層是這樣實現(xiàn)的.實際上把配置文件流交由XMLConfigBuilder進行解析,解析后把所有配置信息封裝到Configuration中,再把Configuration傳遞給DefaultSqlSession-Factory,并實例化這個類在源碼可以看出DefaultSqlSessionFactory是SqlSessionFactory的實現(xiàn)類,所以這個時候就產(chǎn)生了SqlSessionFactory接口的實例..需要openSession,產(chǎn)生SqlSession示例,根據(jù)SqlSession實例執(zhí)行事務。最后要提交事務和關閉SqlSession通常都不關閉SqlSessionFactory,在大點的項目中,都需要用到二級緩存,所以不關閉.Spring框架Spring在實際項目是以ApplicationContext.xml配置文件文件形式存在.當加載ApplicationContext.xml后會產(chǎn)生ApplicationContext容器,在該容器中放置所有管理的對象.這些對象默認都是單例的.通過Scope屬性可以設置對象是否單例.對象中如果還有對象就繼續(xù)進行依賴注入.其實Spring主要核心包括:IoC和AOP。IOC,叫做控制反轉(zhuǎn),所有對象實例化的過程轉(zhuǎn)交給SpringIoC組件,不用程序員手動new對象.目前主流編程語言都是面向?qū)ο笳Z言,經(jīng)常處理對象和對象之間的關系.引入SpringIoC(我們也可以叫DI)可以把我們的關注點從對象之間關系釋放出來,我們只關注業(yè)務邏輯.IoC實際就解析XML或注解后通過反射機制加載對應的類,然后進行實例化或注入里面常用的設計模式包含:單例,工廠等。AOP是面向切面編程.把傳統(tǒng)程序執(zhí)行過程看成縱向執(zhí)行過程,每個方法當作一個點.基于這些點可以進行增強處理。形成了橫向的切面,包含了原有方法和增強方法.不改變原有代碼結(jié)構,添加額外功能.常用AOP功能有事務管理,權限處理,日志打印等。其實Spring的AOP就是對代理設計模式的一個實現(xiàn)。商城開發(fā)工具Ecplipse及其插件Ecplipse介紹:Ecplipse是著名的跨平臺自由集成開發(fā)環(huán)境(IDE)。它本身是一個框架平臺,支持眾多功能,有很強的靈活性。許多軟件開發(fā)商以Ecplipse開發(fā)自己的IDE如MyEcplipse。Eclipse最早由IBM公司開發(fā),2011年貢獻給開源社區(qū),現(xiàn)在它由非盈利軟體供應商聯(lián)盟Eclipse基金會(EclipseFoundation)管理。Eclipse常用插件介紹:SimplePropertieseditor一個簡單實用的文本編輯器插件,可以直接將ANSII漢字或者我們比較熟悉的語種。如在eclipse里面我們通常會實用properties屬性文件,但是如果我們寫的是漢字它會轉(zhuǎn)化成ANsII編碼的格式,使用此插件可以直接將里面的編碼轉(zhuǎn)換成我們想要的漢字。EclipseClassDecompiler 整合了目前最好的2個反編譯工具Jad和JD-Core,并且和EclipseClassViewer無縫集成,能夠方便的使用插件查看類庫源碼,以及采用本插件進行Debug調(diào)試EclipseTomcatPlugin當我們在進行多個web項目開發(fā)或者進行學習的時候,jar包是一個麻煩的事情,我們需要頻繁的去復制粘貼jar,這不僅浪費了大量的時間,而且也占用了較大的存儲空間,而tomcat自定義類加載器就會起到很大的作用,這是tomcat的一個擴展點,而且tomcatplugin也使用這個擴展點自定義了一個loder我們以后就只需要導jar就行了不需要額外的再復制粘貼jar。Tomcat服務器Tomcat服務器是一個免費的開放源代碼的WEB應用服務器。Tomcat是Apache軟件基金會(ApacheSoftwareFoundation)的Jakarta項目中的核心項目,由Apache,Sun和其他一些公司及個人共同開發(fā)而成。因為Tomcat技術先進,性能穩(wěn)定,而且免費,因而深受Java愛好者的喜愛并得到了很多軟件開發(fā)商的認可,是目前比較流行的WEB應用服務器。MySQL數(shù)據(jù)庫MySQL是一個小型關系型數(shù)據(jù)庫管理系統(tǒng),開發(fā)者為瑞典的MysqlLab公司,在2008年被Sun收購。MySQL被廣泛地應用在Internet上的中小型網(wǎng)站。由于體積小,速度快,總體擁有成本低,尤其是開放源代碼這一特點,許多小型公司為了減低成本而選擇MySQL作為網(wǎng)站數(shù)據(jù)庫。但是后來他又被Oracl收購,它以后的發(fā)展或者收費與否還要看Oracl公司如何決斷了。Redis數(shù)據(jù)庫Redis是一個開源的,先進的key-value存儲,并用于構建高性能,可擴展的WEB應用程序的完美解決方案。Redis從它的許多競爭者中脫穎而出主要有以下三個主要特點1)數(shù)據(jù)庫完全在內(nèi)存中,使用磁盤僅用于持久性。2)有豐富的數(shù)據(jù)類型。3)使用簡單方便處理速度快。
商城系統(tǒng)項目需求分析目標基于JavaEE平臺的網(wǎng)上商城是依托于目前主流的SSM框架搭建而成。主要包括兩個方面:一是后臺管理,為管理員提供一些增刪改的權限,改變手工記賬效率慢,成本高的現(xiàn)狀;而前臺方面,給用戶看的主要包括用戶的登陸,購物車的實現(xiàn)等,減少用戶外出購買商品所需時間。商城需要實現(xiàn)的具體目標包括:1)購物商城臺中實現(xiàn)管理員對商品的增加,上架,下架圖片的插入,對商品內(nèi)容的管理包括對商品類目的增加,對商品規(guī)格參數(shù)的修改增加,對大廣告位的插入,對首頁常用圖片的插入。2)購物商城中前臺部分包括實現(xiàn)對商品整個目錄結(jié)構的展示,用戶單點登錄,商品展示,商品詳情以及規(guī)格參數(shù)的展示,商品購買,購物車中商品的增加刪除修改。商城業(yè)務流程圖商城后臺業(yè)務流程圖網(wǎng)站后臺系統(tǒng)是商城的一個核心,通過后臺系統(tǒng)管理員可以對倉庫的商品進行上架,下架,新增的操作,以前這些都是人工操坐,人工記錄,現(xiàn)在則改為由數(shù)據(jù)庫進行一個記錄大大提高了安全性,提高了工作效率,降低了運作成本。如圖3-1是商城的后臺業(yè)務流程圖。圖3-1商城前臺流程圖概況商城前臺務流程圖商城前臺是為客戶準備的頁面,包括會員管理,商品購買,購物車,商品結(jié)算。現(xiàn)在使用這個購買平臺可以留住購買者,利用會員等級制度激發(fā)用戶的購買力,使用數(shù)據(jù)庫來保存用戶的購買記錄,由此來分析用戶喜歡那些商品,那些商品高買的比較少??梢宰顬闃I(yè)務分析的依據(jù),單點登錄(登錄一次其他地方就不用再登錄)由此改善用戶體驗。商城前臺流程圖如圖3-2圖3-2商城后臺流程圖概商城系統(tǒng)詳細設計及實現(xiàn)商城總體開發(fā)架構本商城采用Ecplipse搭建商城項目,EasyUI搭建后臺框架,Git作為版本管理,使用Maven搭建分布式項目并管理架包,使用Linux部署項目。使用Mysql作為持久化存儲介質(zhì),使用Reidis作為緩存數(shù)據(jù)庫提高查詢速度,使用Solr作為全文搜索引擎。商城總體開發(fā)結(jié)構圖如圖4-1:圖4-1商城項目架構圖商城框架實現(xiàn)Spring整合SpringMVCSPRINGMVC作為視圖層的一個框架與SPRING配合使用主要有以下步驟1)配置包掃描器使SPRING可以自動掃描類,不用寫額外的代碼進行識別<context:component-scanbase-package="com.chenfeng.ego.rest.controller"></context:component-scan>2)驅(qū)動注解,給springmvc提供了數(shù)據(jù)綁定的功能<mvc:annotation-driven/>3)視圖解析器,在控制器處理結(jié)束并返回模型和視圖名之后,Spring會依次調(diào)用Spring容器中所注冊的視圖解析器,來查找符合條件的視圖。<beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/jsp/"></property><propertyname="suffix"value=".jsp"></property></bean>4)springmvc自動加載靜態(tài)資源,這樣做的好處是,不必每次請求的時候都需要來加載,而且在某種情況下,這個靜態(tài)資源不適用這個會出錯。<mvc:resourceslocation="/WEB-INF/images/"mapping="/images/**"></mvc:resources><mvc:resourceslocation="/WEB-INF/js/"mapping="/js/**"></mvc:resources><mvc:resourceslocation="/WEB-INF/css/"mapping="/css/**"></mvc:resources><beanid="multipartResolver"class="mons.CommonsMultipartResolver"><propertyname="maxUploadSize"value="100000000"></property><propertyname="maxInMemorySize"value="10000000"></property><propertyname="defaultEncoding"value="utf-8"></property></bean>Spring整合MybatisMybatis作為持久層與SPRING整合主要有以下步驟1)掃描類可以使注解正常使用<context:component-scanbase-package="com.chenfeng.ego.rest.service"></context:component-scan>2)創(chuàng)建數(shù)據(jù)源,連接數(shù)據(jù)庫<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"p:driverClassName="com.mysql.jdbc.Driver"p:url="jdbc:mysql://localhost:3306/ego"p:username="root"p:password="root"></bean>3)創(chuàng)建SqlSessionFactory實例,使我們可以正常使用這個實例對數(shù)據(jù)庫進行操作<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"><propertyname="configLocation"value="classpath:mybatis-config.xml"></property></bean>4)配置事務管理器。<beanid="txManage"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"></bean>5)配置聲明式事物,以那些方法會被攔截<tx:adviceid="txAdvice"transaction-manager="txManage"> <tx:attributes> <tx:methodname="find*"read-only="true"/> <tx:methodname="sel*"read-only="true"/> <tx:methodname="*"/> </tx:attributes></tx:advice>6)配置aop切面,使聲明式事物開始生效。<aop:config><aop:pointcutexpression="execution(*com.chenfeng.ego.rest.service.impl.*.*(..))"id="mypointer"/><aop:advisoradvice-ref="txAdvice"pointcut-ref="mypointer"/></aop:config>7)配置mapper掃描器,這樣就可以只需要寫接口不用寫實現(xiàn)類使dao層簡化,提高開發(fā)效率。<beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"> <propertyname="basePackage"value="com.chenfeng.ego.mapper"></property></bean>Spring整合JedisSpring與jedis結(jié)合使用主要有兩方面的配置1)連接池的配置 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <propertyname="maxTotal"value="30"/> <propertyname="maxIdle"value="10"/> <propertyname="numTestsPerEvictionRun"value="1024"/> <propertyname="timeBetweenEvictionRunsMillis"value="30000"/> <propertyname="minEvictableIdleTimeMillis"value="1800000"/> <propertyname="softMinEvictableIdleTimeMillis"value="10000"/> <propertyname="maxWaitMillis"value="1500"/> <propertyname="testOnBorrow"value="true"/> <propertyname="testWhileIdle"value="true"/> <propertyname="blockWhenExhausted"value="false"/> </bean>Redis集群的配置 <beanid="jedisClients"class="redis.clients.jedis.JedisCluster"> <constructor-argname="poolConfig"ref="jedisPoolConfig"/> <constructor-argname="nodes"> <set> <beanclass="redis.clients.jedis.HostAndPort"> <constructor-argname="host"value="32"/> <constructor-argname="port"value="7001"/> </bean> //…以下還有四個配置服務器地址需要配置配置方法如上一樣 </bean> </set> </constructor-arg> </bean>商城主要功能模塊實現(xiàn)由于使用的是框架技術所以我們使用的依然是mvc三層模型設計,所以每個功能實現(xiàn)也是分層次的POJO層,Service層,Sontroller層,Dao層,以下介紹的時候主要介紹service,Control層代碼設計。商城后臺商品管理實現(xiàn)1)商城商品管理主要就是商品的增刪該查以及其商品的展示。商品展示圖4-1商城后臺頁面操作展示Service層代碼如下其中使用到了pagehelp這個分頁插件privateTbItemParamMapperitemParamMapper;publicEasyUIDataGridshowTbItem(intpage,introws){ EasyUIDataGriddataGrid=newEasyUIDataGrid(); PageHelper.startPage(page,rows); List<TbItem>list=tbItemMapper.selectByExample(new TbItemExample()); PageInfo<TbItem>info=newPageInfo<>(list); dataGrid.setRows(info.getList()); dataGrid.setTotal(info.getTotal()); returndataGrid; }Controller層代碼如下 @RequestMapping("item/list") @ResponseBody publicEasyUIDataGridshow(intpage,introws){ returnthis.tbItemService.showTbItem(page,rows); }商品的上架,下架,編輯,刪除圖4-2商城后臺商品的增刪,下,上架展示Service層代碼如下 @Override publicvoidupStatus(Stringids,bytestatus)throwsException{ TbItemrecord=newTbItem(); List<Long>list=ItemSpiltUtil.idSplit(ids); for(Longlong1:list){ record.setStatus(status); record.setId(long1); tbItemMapper.updateByPrimaryKeySelective(record); } }Controller層代碼其中使用到了封裝的思想,將同樣的代碼封裝起來,因為Service層的代碼都一樣所以使用了一個來判斷簡化了代碼的開發(fā)。是程序看起來更加健壯。@RequestMapping("rest/item/{type}") @ResponseBody publicEgoResultupdataStatus(@PathVariableStringtype,Stringids){ EgoResultegoResult=newEgoResult(); Bytestatus=null; if("delete".equalsIgnoreCase(type)){ status=(byte)3; }elseif("instock".equalsIgnoreCase(type)){ status=(byte)2; }elseif("reshelf".equalsIgnoreCase(type)){ status=(byte)1; } try{ tbItemService.upStatus(ids,status); egoResult.setStatus(200); }catch(Exceptione){ e.printStackTrace(); egoResult.setStatus(400); } returnegoResult; }商城后臺內(nèi)容管理實現(xiàn)商城內(nèi)容管理對內(nèi)容的增加,重命名如圖4-3所示圖4-3商城后臺內(nèi)容管理Service層代碼@ResourceTbContentCategoryMappertbContentCategoryMapper;@OverridepublicList<EasyUiTree>selById(longid){ TbContentCategoryExampleexample=new TbContentCategoryExample(); example.createCriteria().andParentIdEqualTo(id).andStatusEqualTo(1; List<TbContentCategory>list= tbContentCategoryMapper.selectByExample(example); List<EasyUiTree>easyUiTreeList=newArrayList<>(); for(TbContentCategorytbContentCategory:list){ EasyUiTreeea=newEasyUiTree(); ea.setId(tbContentCategory.getId()); ea.setText(tbContentCategory.getName()); ea.setState(tbContentCategory.getIsParent()?"closed": "open"); easyUiTreeList.add(ea); } returneasyUiTreeList; } @Override publicEgoResultinsertByid(longparentId,Stringname) { EgoResultegoResult=newEgoResult(); TbContentCategorytbContentCategory=newTbContentCategory(); tbContentCategory.setCreated(newDate()); tbContentCategory.setId(IDUtils.genItemId()); tbContentCategory.setIsParent(false); tbContentCategory.setName(name); tbContentCategory.setParentId(parentId); tbContentCategory.setSortOrder(1); tbContentCategory.setStatus(1); tbContentCategory.setUpdated(newDate()); TbContentCategoryExample example = new TbContentCategoryExample(); example.createCriteria().andNameEqualTo(name); intcount=this.tbContentCategoryMapper.countByExample(example);if(count<1){intresult= this.tbContentCategoryMapper.insert(tbContentCategory); if(result>0){ TbContentCategoryparent=newTbContentCategory(); parent.setId(parentId); parent.setIsParent(true); intre= this.tbContentCategoryMapper.updateByPrimaryKeySelective(parent); if(re>0){ egoResult.setStatus(200); }else{ egoResult.setStatus(400); } }else{ egoResult.setStatus(400); } }else{ egoResult.setStatus(400); } returnegoResult; }商城前臺單點登錄的實現(xiàn)單點登錄原理簡述:要想實現(xiàn)Cookie-Redis總得有個Cookie吧,所以第一步要先創(chuàng)建一個Cookie,然后Cookie起個名字,(因為我們要判斷瀏覽器端是否存在這個cookie所以說需要專門寫一個js這個js是前臺寫的,跟后續(xù)其他的需要登錄的網(wǎng)頁相關聯(lián),其他的網(wǎng)頁要引入這個js,當判斷Cookie有了之后就會將這個js就會獲取第一個js里面的Cookie值,之后就可以從Redis查詢數(shù)據(jù)了)Cookie的值為UUid,然后將這個UUid作為key存儲到Redis中他的值為用戶信息,同時設置Redis的失效時間。每一個需要用戶信息的頁面都要有兩個js上面提到的,第一個js要判斷是否存在這個Cookie,第二個js是先獲取Cookie里面的值然后發(fā)送一個Jsonp請求,從Redis里面獲取,然后進行相應的展現(xiàn)。Rdis-Cookie就是對Cookie-Jsessin的模擬。單點登錄service層代碼如下@ResourceprivateTbUserMapperusermapper;@ResourceprivateJedisDaodao; @Override 當用戶登錄的時候要創(chuàng)建Cookie存值為UUid,UUid將最為Redis的key 內(nèi)存User對象Usr對象經(jīng)過工具類轉(zhuǎn)換 PublicEgoResultlogin(TbUsertb,HttpServletRequest req,HttpServletResponseres){ tb.setPassword(DigestUtils.md5DigestAsHex(tb.getPassword().getBytes ())); EgoResultego=newEgoResult(); TbUserExampleexample=newTbUserExample(); example.createCriteria().andUsernameEqualTo(tb.getUsername()).andPa sswordEqualTo(tb.getPassword()); List<TbUser>list=usermapper.selectByExample(example); if(list!=null&&list.size()>0) { Stringuuid=UUID.randomUUID().toString(); dao.set("user-"+uuid,JsonUtils.objectToJson(list.get(0))); System.out.println(list.get(0)); dao.expire("user-"+uuid,30*60); CookieUtils.setCookie(req,res,"TT_TOKEN",uuid,30*60); ego.setStatus(200); ego.setData(uuid); }else{ ego.setStatus(400); } returnego; } publicEgoResultgetTokenResult(Stringtoken,HttpServletRequest req,HttpServletResponseres) { EgoResultego=newEgoResult(); Stringstring=dao.get("user-"+token); ego.setStatus(200); ego.setData(JsonUtils.jsonToPojo(string,TbUser.class)); dao.expire("user-"+token,30*60); CookieUtils.setCookie(req,res,"TT_TOKEN",token,30*60); returnego; } 注冊頁面注冊成功之后會跳轉(zhuǎn)到登錄頁面而登錄頁面登錄地址的參數(shù) 將帶有此次相應結(jié)果的rfferer參數(shù)就可以成功跳回到登錄之前的頁面 @RequestMapping("user/showRegister") publicStringresigin(@RequestHeader(name="Referer")String referer,Modelmodel) {model.addAttribute("url",referer); return"register"; } @RequestMapping("user/check/{countent}/{type}") @ResponseBody publicEgoResultcheck(@PathVariableStringcountent,@PathVariable inttype){ returnuserService.check(countent,type); } @RequestMapping("/user/register") @ResponseBody publicEgoResultregister(TbUseruser)} returnuserService.register(user); }商城前臺solr全文搜索的實現(xiàn)商城前臺使用的是solr全文solr引擎Solr管理集群的結(jié)構圖如圖4-5圖4-5商城solr集群結(jié)結(jié)構圖主要步驟以及代碼如下在使用之前要對Solr進行初始化,在初始化之后Solr中就會建立索引的一些聯(lián)系。當用戶查詢數(shù)據(jù)的時候會直接在初始化的文件中對數(shù)據(jù)進行搜索Service層代碼如下@Resource privateSolrMappermapper; @Value("${zkHost}") privateStringzkHost; @Override publicStringinitSolr()throwsSolrServerException,IOException{ List<ItemSearch>list=mapper.seAll(); CloudSolrServerserver=newCloudSolrServer(zkHost); server.setDefaultCollection("collection1"); for(ItemSearchitemSearch:list){ SolrInputDocumentdoc=newSolrInputDocument(); doc.addField("id",itemSearch.getId()); doc.addField("item_category_name", itemSearch.getItem_category_name()); doc.addField("item_desc",itemSearch.getItem_desc()); doc.addField("item_image",itemSearch.getItem_image()); doc.addField("item_price",itemSearch.getItem_price()); doc.addField("item_sell_point", itemSearch.getItem_sell_point()); doc.addField("item_title",itemSearch.getItem_title()); server.add(doc); }mit(); return"ok"; } publicSearchResultselByQ(Stringq,intpage,introws)throws SolrServerException{ SearchResultsear=newSearchResult(); CloudSolrServerserver=newCloudSolrServer(zkHost); server.setDefaultCoection("collection1"); SolrQueryquery=newSolrQuery(); query.setQuery("item_keywords:"+q); query.setStart((1)*rows); query.setRows(rows); query.setHighlight(true); query.addHighlightField("item_titleitem_sell_point"); query.setHighlightSimplePre("<spanstyle='color:red'>"); query.setHighlightSimplePost("</span>"); QueryResponseresponse=server.query(query); SolrDocumentListlist=response.getResults(); longcount=list.getNumFound(); sear.setTotalPages(count%rows==0?count/rows:count/rows+1); sear.setPage(page); List<ItemSearch>listResult=newArrayList<>(); Map<String,Map<String,List<String>>>map= response.getHighlighting(); for(SolrDocumentdoc:list) { ItemSearchis=newItemSearch(); is.setId(Long.parseLong(doc.get("id").toString())); is.setItem_category_name(doc.get("item_category_name").toString());is.setItem_image(doc.get("item_image").toString()==null?"":doc.get("item_image").toString().split(",")[0]); is.setItem_price(Long.parseLong(doc.get("item_price").toString())) returnsear; }}
商城系統(tǒng)運行結(jié)果商城后臺運行結(jié)果商城前臺新增產(chǎn)品管理員新增商品:當用戶想在數(shù)據(jù)庫里面增加商品的時候有幾個要點要注意管理員新增商品的時候有商品類目這個商品類目是按照一個樹狀結(jié)構展示的是由EasyUI框架提供的向數(shù)據(jù)庫里面查詢數(shù)據(jù)。商品的一個圖片上傳是用的vsftpt代理服務器進行操作的我們實際上上傳的圖片最終存儲的位置是在一個遠程調(diào)用的服務器上存儲的新增商品的時候用到了一個數(shù)據(jù)庫的模板設計模式。他的思想是兩個表之間自動建立聯(lián)系交給中間的一個代理做模板的處理具體操作如圖5-1所示圖5-1增加商品的操作當我們在進行如上操作結(jié)束之后,利用SQL工具的查詢語句直接在數(shù)據(jù)庫里面進行一個查詢操作可以得到如下結(jié)果,由此可見上述操作沒有問題圖5-2數(shù)據(jù)庫中查詢出來的商品商城前臺商品內(nèi)容管理通過如圖5-1,5-2的相關信息可以得出結(jié)論,增加商品的時候數(shù)據(jù)庫里面會同步存儲相應的商品。當對內(nèi)容進行一些增加,刪除,修改操作的時候觀察數(shù)據(jù)庫是否會進行相應的變化如下圖所示5-3進行相應的操作圖5-3商品內(nèi)容的添加如果5-4當進行了如上圖的增加操作的時候數(shù)據(jù)庫里面已經(jīng)有了剛才添加的內(nèi)容,由此可證明內(nèi)容管理中的增加是沒有問題的。篇幅所限制刪除,修改就不在這里繼續(xù)演示了圖5-4數(shù)據(jù)庫中的內(nèi)容商城前臺運行結(jié)果商城前臺用戶搜索在商城的用戶搜素模塊,當我們輸入想要購買的物品的時候如圖5-5,請求會首先經(jīng)過web.xml然后再通過遠程調(diào)用請求Solr這個WEB項目中的一個文件,然后對數(shù)據(jù)進行一個查詢操作,這點要注意的是這次查詢將不會再數(shù)據(jù)庫里面進行一個查詢操作。圖5-5搜索頁面當我們輸入要搜索的物品之后,在Solr文件里面經(jīng)過查詢之后,會將結(jié)果返回到WEB頁面WEB頁面里面的相關代碼會將查詢的結(jié)果進行一個分頁的操作然后會將查詢結(jié)果的第一頁進行具體結(jié)果顯示如圖5-6圖5-6搜索結(jié)果頁面商城前臺用戶注冊當用戶進行注冊的時候?qū)袔讉€判斷條件1)用戶的手機號是否已經(jīng)注冊如果沒有注冊則會提示注冊成功如圖5-8如果用戶已經(jīng)注冊過將會提示用戶已經(jīng)注冊過該手機如圖5-72)當用戶的密碼不一致時提示用戶的密碼不一致3)當用戶的密碼與要求的密碼不一致或者密碼過短的時候也會提示注冊失敗圖5-7用戶注冊失敗圖5-8用戶注冊成功商城用戶購物車商城購物車可以說是整個業(yè)務的最核心之一也不為過,因為商城存在的目的就是買與賣,沒有這個后續(xù)的很多東西都無法展開。下面就詳細的講下購物車以及它的測試當用戶點擊想要購買的物品的時候要進行一個基于AOP的攔截器的操作,首先要進行一個判斷,判斷用戶是否已經(jīng)登錄,如果用戶登錄過來則可以進行商品的購買加入購物車如圖5-9所示的購物車。如果用戶沒有登錄過則會跳轉(zhuǎn)到登錄頁面進行登錄。圖5-9加入購物車當用戶登錄成功之后用戶購買的物品就可以在購物車上顯示出來了,具體的顯示效果如下圖5-10所示,當用戶添加了一個平板電腦之后在網(wǎng)頁上顯示出來。圖5-10購物車顯示當用戶選完物品之后可以進行一系列的操作,如用戶想增加已經(jīng)購買的商品的數(shù)量的候可以點擊加號,當用戶想減少自己購買的物品的數(shù)量的時候可以點擊減號,當用戶不想要購物車的商品的時候點擊減號即可,這就是購物車的基本功能而且通過圖5-10和圖5-11我們也可以知道當減少增減物品的時候他的價格也可以正確的變化圖5-11購物車的商品進行操作總結(jié)以及展望本項目使用了當前流行的SSM框架技術,是一個B2B的商城項目,本項目著重對管理員的操作,以及用戶的一些操作做了簡單的介紹,對于支付模塊這點還沒有做過相應的介紹,還有的不足是單點登錄是一個偽登錄做的還不夠完善。對于頁面的優(yōu)化做的也不是太好。未來的展望是本項目將使用阿里系的Dubbo這個流動式的微服務架構搭建分布式項目,優(yōu)點就是簡單易用,可以動態(tài)的調(diào)節(jié)連接數(shù)。然后在頁面優(yōu)化方面用HTML5進行一定的特色布局。相信商城在這些技術的支持下一定會變的越來越好。為商家和廣大用戶提供更好的服務,讓我們的生活變的更加愉悅。[1](美)BruceEckel著.Java編程思想[M].陳昊鵬等譯.北京:基機械工業(yè)出版社,2007:100-150.[2](美)CraigWalls著.SpringINACTION[M].張衛(wèi)濱譯.第四版:北京.張衛(wèi)濱譯:人民郵電出版社.2016:78-90.[3](美)W.RichardStevens著.TCP/IP詳解卷1:協(xié)議[M]范建華,胥光輝,張濤譯.謝希仁校.北京:機械工業(yè)出版社,2013:90-110.[4]鳥哥.Linux私房菜基礎學習篇(第三版)[M].北京.人民郵電出版社,2010:120-200.[5]唐漢明,翟振興,關寶軍,王洪權,黃瀟.深入淺出MySql數(shù)據(jù)庫開發(fā)[M],優(yōu)化與管理維護(第2版)北京:人民郵電出版社,2014:150-200.[6](美)JonLoeliger著Git版本控制管理[M].王迪譯.北京:人民郵電出版社250-300.[7](美)David.PattersonJohnL著.計算機組成與設計硬件/軟件接口[M].康繼昌.樊曉椏譯.北京:機械工業(yè)出版社,2010:55-60.[8](美)FreederickP.Brooks著.人月神話[M].UMLChina翻譯組.汪穎譯北京:清華大學出版社,2014:70-150.[9](美)EricFReeman&ElisabethFreemanwithKathySierra&BertBates著HeadFirst設計模式[M]O.ReillyTaiwan公司譯UMLChina改編:北京人民郵電出版社,2014:100-150.[10]July著編程之法面試和算法心得[M]北京:人民郵電出版社,2016:55-80.[11]盧瀚.王春斌等編著Java開發(fā)實戰(zhàn)1200例[M]北京:清華大學出版社,2012:70-150[12]張桂珠,劉麗,陳愛國java面向?qū)ο蟪绦蛟O計[M](第2版)北京:機械工業(yè)出版社,2008:70-80.[13]高林,周海燕.Jsp網(wǎng)上書店系統(tǒng)與案例分析[M].清華大學出版社,北京:2005:110-115.[14]劉騰紅,孫細明.信息系統(tǒng)分析與設計[M].清華大學出版社,2003:99-110.[15]林邦杰,徹底研究java[M].北京:電子工業(yè)出版社,2002:65-70.致謝當我論文完成的那一刻,我的心情萬分激動。在論文的選題以及編寫的過程中我得到了很多的幫助。首先,也是最主要感謝的是我的指導老師,老師。在論文的編寫過程中,他給了我極大的幫助,幫助我指出了論文中的很多不足,以及指導意見。我在老師的指導中看到了他對對學術態(tài)度的嚴謹。讓我學到了對待任何正式的事物都要保持這種態(tài)度,這也是我們前進的動力更是成功的關鍵。在論文的編寫過程中,我要感謝周圍的老師和同學,他們耐心的幫我指出了錯誤,并相互促進讓我學到了許多老師以及同學解決問題的好辦法。在此十分感謝各位老師以及同學對我的幫助。最后,也要特別感謝審閱和論文答辯組的各位老師,對你們的付出我表示深深的感謝?;趩纹瑱C的單晶金剛石刀具刃磨設備的數(shù)控改造基于單片機的溫度智能控制系統(tǒng)的設計與實現(xiàn)基于MSP430單片機的電梯門機控制器的研制基于單片機的氣體測漏儀的研究基于三菱M16C/6N系列單片機的CAN/USB協(xié)議轉(zhuǎn)換器基于單片機和DSP的變壓器油色譜在線監(jiān)測技術研究基于單片機的膛壁溫度報警系統(tǒng)設計基于AVR單片機的低壓無功補償控制器的設計基于單片機船舶電力推進電機監(jiān)測系統(tǒng)基于單片機網(wǎng)絡的振動信號的采集系統(tǒng)基于單片機的大容量數(shù)據(jù)存儲技術的應用研究基于單片機的疊圖機研究與教學方法實踐基于單片機嵌入式Web服務器技術的研究及實現(xiàn)基于AT89S52單片機的通用數(shù)據(jù)采集系統(tǒng)基于單片機的多道脈沖幅度分析儀研究機器人旋轉(zhuǎn)電弧
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2030年中國大型振動試驗機行業(yè)市場分析報告
- 2024-2030年中國即時通訊(im)行業(yè)競爭格局及投資創(chuàng)新模式分析報告
- 眉山職業(yè)技術學院《電子商務概論》2023-2024學年第一學期期末試卷
- 2024年度食品代加工與產(chǎn)品質(zhì)量追溯協(xié)議3篇
- 2024年標準化物業(yè)租賃協(xié)議模板匯編版B版
- 2024年物聯(lián)網(wǎng)農(nóng)業(yè)技術開發(fā)與合作合同
- 2024年標準股權轉(zhuǎn)讓協(xié)議一
- 馬鞍山師范高等??茖W?!冬F(xiàn)場節(jié)目主持實踐》2023-2024學年第一學期期末試卷
- 2024年城市綜合體土地房屋股權轉(zhuǎn)讓與建設合同范本3篇
- 2024年度特色民宿商品房承包銷售合同3篇
- YY/T 0471.4-2004接觸性創(chuàng)面敷料試驗方法 第4部分:舒適性
- YY/T 0251-1997微量青霉素試驗方法
- YC/T 559-2018煙草特征性成分生物堿的測定氣相色譜-質(zhì)譜聯(lián)用法和氣相色譜-串聯(lián)質(zhì)譜法
- GB/T 29309-2012電工電子產(chǎn)品加速應力試驗規(guī)程高加速壽命試驗導則
- 齊魯工業(yè)大學信息管理學成考復習資料
- 公務員面試-自我認知與職位匹配課件
- 中頻電治療儀操作培訓課件
- 柔弱的人課文課件
- 動物寄生蟲病學課件
- 電梯曳引系統(tǒng)設計-畢業(yè)設計
- 三度房室傳導阻滯護理查房課件
評論
0/150
提交評論