【我的向】Vue+SSH商城小項目の小結

前言

這一切都關於咱們JAVA老師佈置的一個商城系統大做業,由於年糕君主攻前端方面啦,因此在JAVA框架上絕對是一個萌新,不過秉着老師說的學會一個框架只要半天的說法,最後大概一個禮拜的時間,仍是馬馬虎虎達到了這樣那樣的功能。
這其中出了不少BUG(並且作的進度曾讓我感受很崩潰😭)~好不容易結課了,因此來好好總結一下。
【P.S】固然我這應該有一些不合理的設計和開發方法(嚴肅)!但願各位看官能溫柔一點,有錯誤或更好意見歡迎告訴我。前端

技術和工具

前端相關:Vue.js、Vue-cli、webpack
後端相關:struts2.0、Spring 3.一、Hibernate 三、JUnit 四、MyEclipese
數據庫相關:MySQL 5.5vue

實現的需求

頁面需求:
頁面我是在網易雲商城的基礎上進行了修改(由於我熱愛音樂呀),寫了一個首頁、商品詳細頁面、購物車頁、個人訂單頁和登陸註冊頁。java

功能需求:webpack

  • 登陸、註冊(判斷輸入合法)
  • 首頁顯示、分類顯示、搜索
  • 購物車、訂單顯示

前端相關

狀況1:使用Vue-cli搭建了多頁面的應用
我這個小項目雖然使用了Vue來作,可是仍是想作成多頁面的。由於我感受這幾個頁面之間可複用的組件不多,從新空一個頁面出來寫也不要緊。
由於也看過一些相似的文章來說解如何配置,因此這裏修改一下Vue-cli的配置就容易達成目的。不過也感受到這樣在每次啓動webpack進行第一次打包的時候會很慢。ios

狀況2:未使用vue-router進行跳轉
由於是多頁面因此直接跳轉就能夠了,可是在某些頁面內能夠局部根據URL的改變來改變內容。這裏用了vue-router的原理來進行檢測,根據URL的哈希改變和監聽就能夠完成預期的想法(噗後來回想起來用?來GET方法不也差很少啊...不過這樣就會有明顯的頁面跳轉)。web

window.location經常使用的屬性:spring

hash 從井號 (#) 開始的 URL(錨)
host 主機名和當前 URL 的端口號
hostname 當前URL的主機名
href 完整的URL
pathname 當前URL的路徑部分
port 當前URL的端口號
protocol 當前 URL 的協議
search 從問號 (?) 開始的 URL

狀況3:關於vuex的使用
由於是多頁面,因此vuex能夠說是沒啥做用QAQ,由於每個頁面都是本身有一個根store,因此它們之間的數據變化是交互不了的,因而最後這個小項目沒有使用vuex。vue-router

狀況4:跨域的問題
雖然使用了axios,可是跨域的問題仍是會有的,而且後面發現很棘手的就是cookie都是不攜帶的,小項目使用了後臺進行CORS設置來幫助它跨域。sql

axios.defaults.withCredentials = true

狀況5:無關係的組件間通訊
在根部加入一個Vue實例,經過它來進行一個事件傳播的中轉,也就是所謂的EventBus,一樣的網上也有不少相似的文章。(不必定是$root,也多是$root.$root,要見具體狀況而言)
詳解Vue 非父子組件通訊方法(非Vuex)vuex

狀況6:localStorage
localStorage只能存字符串,因此要用JSON.parseJSON.stringify進行相互轉換而後操做。

狀況7:Vue和style
這個我老是沒記清楚,直接嵌入綁定的時候,有[...],也有{...}
數組的形式

:class="[classA, classB]"
:class="['tip', usernameTip.length <= 0 ? 'hidden ': '']
:class="[classA, { classB: isB, classC: isC }]

對象的形式

:class="{ 'class-a': isA, 'class-b': isB }

狀況8:給數組包含的對象的屬性賦值,Vue不會檢測到更新
使用在內部就是使用this.$set(數組成員[索引], '屬性名', 值)能夠實現。

狀況9:多個異步
也就是想發送多個異步請求,最後整合它們的結果。可是每每是直接執行後面的同步代碼了,因此會出現渲染的時候拿到的東西是空。由於時間不夠,我用了之前的作法,就是遞歸調用來解決。

狀況10:this的指向
在調用別的組件後,在它的內部這個this極可能就會被修改了,這個時候箭頭函數的好處就來了,不須要再定義一個臨時變量來存着vue的this。

狀況11:對於前端安全的理解
作的時候,我就想着,對象數據之類的在控制檯都彷佛能夠很容易的改變,這樣能夠繞過去發送請求。可是在之前也是這樣的啊,因此說前端原本就是不安全的,因此在後臺也必定要作相應的處理措施。而之因此前臺也要作一些驗證控制,也一樣是能夠方便正經常使用戶的體驗和使用,不用等待後臺發回消息的時間這樣。

狀況12:font-awesome的使用
打包出來的時候,會顯示不了圖標,還要本身在頁面引入一個連接。

後端相關

下面以一個萌新的視角來闡述關於SSH的種種:

  • struts:它的action至關因而servlet的做用,也就是咱們訪問後臺配置的URL(默認是.action)都是它提供的。
  • Spring:通常狀況下,咱們都是調用某個類的某個方法,這樣總要建立一個對象來調用,有了它去注入接口,就能夠直接調用接口.方法來完成任務。
  • Hibernate:簡化也更安全化了對數據庫的操做。

結構

圖片描述

  • mysho下放了Hibernate默認建立的類HibernateSessionFactory
  • mysho.action放了全部的Action類,包括UserAction、CartAction和ShowAction,它們會有一個service的成員來調用對應的方法;
  • mysho.service放的是service類,這裏直接調用Dao類進行相應的操做。
  • mysho.dao放的是全部和數據庫進行操做的Dao類;
  • mysho.model放的是全部類原型,包括User、Item(商品)、Order(訂單)和Type;
  • mysho.utils是工具類,輔助操做。

框架的整合

建議使用IDE本身的配置~這樣方便統一換包啥的。若是出現配置文件和框架jar包都沒啥錯誤的狀況下仍是出現了問題,並且怎麼百度都搜不到,請考慮如下方法:

  • 更換JDK的版本
  • 更換某個框架的版本
  • 若是無論怎麼改仍是出現了一樣的錯誤,請點擊Project -> clean,清除緩存。若是沒用,就打開Tomcat的文件夾看看裏面部署的內容修改了嗎,若是一直不改,就換一個workspace吧。

配置Hibernate

這裏我沒有用逆向工程,Spring的注入方式也是setter注入。
除了默認給配置的,還須要寫hbm.xml文件的映射:

<mapping resource="com/mysho/model/User.hbm.xml" />

若是在項目中使用了openSession,還須要配置:

<property name="hibernate.current_session_context_class">thread</property>

配置以UTF-8編碼進行鏈接,防止中文亂碼:

<property name="connection.characterEncoding">utf-8</property>

配置Spring

由於使用的是setter注入,因此在這裏必需要寫清楚全部要注入的數據的內容。好比:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation" value="classpath:hibernate.cfg.xml">
    </property>
</bean>

<bean id="userDao" class="com.mysho.dao.UserDaoImp">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

這裏配置了兩個bean,一個叫作sessionFactory,一個叫作userDao,userDao裏面配置了一個sessionFactory的屬性,它指向(ref)id是sessionFactory的東西,因此這樣運行的時候Spring就知道應該注入什麼。

配置Struts

這裏有一個巨大的坑!並且以前百度了很久都沒有搜索到正確的答案。
若是配置好項目,可是發現全部的接口成員都是null,那麼請考慮是否是這個問題:

<action name="showIndexItem" class="showAction" method="showIndexItem"/>

配置action的時候,它所指向的class,請寫Spring中id對應的那個action的class,不能寫成包.class,由於這樣,Struts就不會通過Spring的注入,由於你更本沒把它們兩個聯繫起來。
另外還有配置編碼:

<constant name="struts.i18n.encoding" value="utf8" />

配置web.xml

<!-- ***Spring 容器初始化*** -->
<context-param>        
    <param-name>contextConfigLocation</param-name>        
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<listener>
    <listener-class>
        org.springframework.web.util.IntrospectorCleanupListener
    </listener-class>
</listener>

<!-- 配置編碼 -->
  <filter>
<filter-name>characterEncodingFilter</filter-name>  
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
    <init-param>  
        <param-name>encoding</param-name>  
        <param-value>utf-8</param-value>  
    </init-param>  
    <init-param>  
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>  
    </init-param>  
</filter>  
 <filter-mapping>  
    <filter-name>characterEncodingFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  

 <!-- ******Struts2核心過濾器*****  -->
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注意啦,這裏的org.apache.struts2.dispatcher.FilterDispatcher是由於個人strut是2.0版本的,版本很低,高版本的寫法不是這樣的。

其餘

狀況1:配置跨域

response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", 你的URL);
response.setHeader("Access-Control-Allow-Methods", 你的方法);

這裏若是Access-Control-Allow-Credentials爲true的話,Access-Control-Allow-Origin不容許設置爲*,必須精確填一個地址。

狀況2:以JSON形式返回

response.setHeader("Content-Type", "application/json");

由於使用了先後端分離,因此必然要返回JSON了~這樣雖然struts有一個JSON插件包,可是因爲個人版本一直匹配不上,我就找到了一種最原始的方法來實現,可是實際上並不建議這樣作。另外一方面action進行配置:

<package name="default" namespace="/" extends="struts-default">
    <action name="checkname" class="userAction" method="checkUsername"/>
</package>

向checkname.action發送請求便可,雖然控制檯會出現一個警告說未設置成功/失敗的跳轉頁面,可是實際上不影響使用。

狀況3:報錯難以排除問題根源
那麼請使用JUnit來編寫測試用例吧!
這個方法真的超級好使,不過在測試Spring的時候,須要手動從配置文件中去提取出容器來,或者使用注入的方式來實現提取容器,百度都有不少文章。

狀況4:關於setter注入
每一個要被注入的接口成員須要有對應的setter方法,另外所在的類也須要一個沒有參數的構造函數。

狀況5:關於hql語句
注意:=這個符號,它的先後不要留空格:

from com.mysho.model.User user where user.username=:usernam

設置開始尋找的位置,以及獲取的條數:

query.setFirstResult(start);
query.setMaxResults(size);

若是未求使用事務,控制檯報錯,改爲事務的形式就好了:

Session s = sessionFactory.getCurrentSession();
Transaction  transaction = s.beginTransaction();
...
transaction.commit();

狀況6:session獲取不一致
就是在這裏設置了session的值,但在另外一個地方卻拿到的是空,
這個時候就要考慮應該是由於它們根本就不在一個容器內,
由於發送請求的時候必需要帶上相應的cookie才能識別~
但也有辦法讓全部容器共享數據,使用:

ServletActionContext.getServletContext().getAttribute(...)
ServletActionContext.getServletContext().setAttribute(..., ...)

狀況7:JSON轉換的問題JSONArray.fromObject(...):把一個list轉換爲JSON。JSONObject.fromObject(...):把一個Object轉換爲JSON。另外對象中存在Date類型的JSON會報異常,須要另外作更多特殊處理才行,而且使用java.sql.Date和java.util.Date來操做的話又會有不一樣結果。

相關文章
相關標籤/搜索