存在用戶的系統(tǒng),必然需要用戶的登錄和認(rèn)證,今天就通過(guò)分析Spring中自帶的jpetstore的例子來(lái)學(xué)習(xí)一下如何實(shí)現(xiàn)在Spring構(gòu)架的系統(tǒng)中用戶登錄。
1、首先從注冊(cè)用戶開(kāi)始,先看看jpetstore-servlet.xml中關(guān)于注冊(cè)用戶的bean定義,從定義命名中就可以看出下面這段就是注冊(cè)用戶的:
<bean name="/shop/newAccount.do" class="org.springframework.samples.jpetstore.web.spring.AccountFormController">
<property name="petStore"><ref bean="petStore"/></property>
<property name="validator"><ref bean="accountValidator"/></property>
<property name="successView"><value>index</value></property>
</bean>
1). formView呢?從AccountFormController的構(gòu)造函數(shù)中得到,原來(lái)為EditAccountForm;
2). EditoAccountForm.jsp中顯得非常亂,其實(shí)沒(méi)有多少難理解的地方,最主要的是這個(gè)form既是添加新用戶的,又是編輯用戶信息的,所以顯得有點(diǎn)亂糟糟的。
2、添加好了新用戶,接下來(lái)看看如何登錄,在jpetstore-servlet中發(fā)現(xiàn)這兩個(gè)相關(guān)bean定義,如下:
<bean name="/shop/signon.do" class="org.springframework.samples.jpetstore.web.spring.SignonController">
<property name="petStore"><ref bean="petStore"/></property>
</bean>
<bean name="/shop/signonForm.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
<property name="viewName"><value>SignonForm</value></property>
</bean>
1).
第二個(gè)bean是在運(yùn)行時(shí)用戶輸入用戶名和密碼的form,叫做SignonForm,對(duì)于這個(gè)
ParameterizableViewController,用文檔里的話說(shuō)這是最簡(jiǎn)單的Controller,其作用就是在運(yùn)行中指向
Controller而不是直接指向jsp文件,僅此而已。
2).
SignonForm.jsp,里面就是一個(gè)簡(jiǎn)單的form,其action就是第一個(gè)bean,即/shop/signon.do,最需要注意的是
signonForwardAction,其主要作用是forward到需要輸入用戶名和密碼的那個(gè)頁(yè)面上去,這個(gè)變量哪里來(lái)的呢?看看下面:
<bean id="secureHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="signonInterceptor"/>
</list>
</property>
<property name="urlMap">
<map>
<entry key="/shop/editAccount.do"><ref local="secure_editAccount"/></entry>
<entry key="/shop/listOrders.do"><ref local="secure_listOrders"/></entry>
<entry key="/shop/newOrder.do"><ref local="secure_newOrder"/></entry>
<entry key="/shop/viewOrder.do"><ref local="secure_viewOrder"/></entry>
</map>
</property>
</bean>
原來(lái),上面的signonInterceptor實(shí)現(xiàn)了preHandle,因此在請(qǐng)求上面的map頁(yè)面時(shí),首先要經(jīng)過(guò)這個(gè)Interceptor,看看
SignonInterceptor的源碼,原來(lái)在其中為signon.jsp賦予一個(gè)signonForwardAction對(duì)象,呵呵,總算明白了。
3).
接下來(lái)去學(xué)習(xí)一下SignonController,其主體部分中可以看出,首先取出用戶輸入的username和password,然后到數(shù)據(jù)庫(kù)中驗(yàn)證
有沒(méi)有這個(gè)用戶,如果沒(méi)有這個(gè)用戶,返回各錯(cuò)誤頁(yè)面;如果成功,首先生成一個(gè)UserSession對(duì)象,在request的session加入這個(gè)
userSession,注意這部分代碼中給出了PagedListHolder分頁(yè)的簡(jiǎn)單使用方法,關(guān)于分頁(yè)顯示,以后再學(xué)習(xí)吧。
3、登錄成功后,就可以根據(jù)不同的用戶設(shè)施不同的行為了,取得用戶信息,無(wú)非就是從session取出userSession即可。