學習總結(2)

61. 對於 JndiObjectFactoryBean 查找 jndi 資源未提及,如何設置 jndiEnvironment 屬性,如果是在J2EE容器中運行,沒什麼問題,只是以單獨應用程序運行就會錯,如下在容器外運行需要加上 jndiEnvironment 配置,指定實現類,及URL等

<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">
org.apache.naming.java.javaURLContextFactory
</prop>
<prop key="java.naming.factory.url.pkgs">
org.apache.naming
</prop>
</props>
</property>


62.發送電子郵件配置 SimpleMailMessage 時也未說明,如果 SMTP 發送前需要驗證該如何配置。需加上 mail.smtp.auth屬性爲 true,和驗證時用戶名和密碼,Spring 驗證時是通過 getTransport("smtp").connect(host,user,passwd) 來驗證的。
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
<property name="host">
<value>mail.2911.net</value>
</property>
<property name="username">
<value>unmi</value>
</property>
<property name="password">
<value>unmi1234</value>
</property>
</bean>

這樣取到mailSender後,就能調用它的send(SimpleMailMessage msg)發送郵件,自動進行密碼驗證。Spring也還是不夠完美,可以配置 JavaMailSenderImpl 的 session 屬性,但卻無法應用上 session.getProperties() 中的許多項配置。Spring中能配置 SimpleMailMessage,然後再配合 Velocity 的郵件內容模板,確實很方便


63. 搭配Spring的ScheduledTimerTask和jdk的TimerTask,再配置TimerFactoryBean就會自動啓動定時器了,這種方式可配置的參數太少了,只能設置從現在開始隔多久(delay)以什麼頻度(period)執行某個任務

64. 更高級的定時器用 Quartz 來調度,這個工具以前單獨使用過,可像Unix的cron那般靈活配置。在MyEclipse中使用Quartz時需要引入 Spring 1.2 Misc Libraries 所包含的包(含quartz-1.5.2.jar)

65. 94,96,97,104這幾頁中配置<value ref=""/>要寫成<ref bean=""/>纔對

66. 從前往後的被包容關係是:JobClass->JobDetailBean->Trigger->TimerFactoryBean, 有兩種Trigger,分別是 SimpleTriggerBean 和 CronTriggerBean。SimpleTriggerBeanScheduledTimerTask基本等價,Quartz的威力全部體現在 CronTriggerBean 上的,可靈活的配置它的cronExpression屬性控制排程,最後需配置 SchedulerFactoryBean (它和TimerFactoryBean是基本等價) 來啓動定時器

67. MethodInvokingTimerTaskFactoryBean+ScheduledTimerTask+TimerFactoryBean 可定時調用某個類(或對象)的某個方法,這個類只需要是一個普通Java類,被調度的方法不能有參數

68. MethodInvokingJobDetailFactoryBean+SimpleTriggerBean(或CronTriggerBean)+SchedulerFactoryBean 定時調用某個類(或對象)的某個方法,這個類只需要是一個普通Java類,被調度的方法不能有參數

69. 書中並未描述 0/10 每10個單位觸發執行的配置形式,需注意 */? 的使用,定義好 CronExpression 後需好好測試真正形爲

70. Spring 調用 JMS 發送消息的用法先擱一下,在SOA/MQ 的大環境下一定派得上用場的

[b]Spring mvc[/b]

71. Spring 的 MVC 和 Struts 的 MVC 基本一致
Spring 的控制流程是:請求->DispatcherServlet->從 HandlerMapping 中查詢到處理該請求的 Controller-> Controller 的 handleRequest 方法調用業務方法,最後返回 ModelAndView (ModelAndView告訴了 DispatcherServlet 轉向到哪個視圖)
Struts 的控制流程是:請求->ActionServlet->從 ActionMapping 中查詢到處理該請求的 Controller (Action類)->Action 的execute 方法調用業務方法,最後返回 ActionForward (ActionForward告訴了 ActionServlet 該轉向到哪個視圖)
72. Spring 的 DispatcherServlet 和 Struts 的 ActionServlet 的配置方式是一樣的,都是作爲一個自啓動的 Servlet 配置到 web.xml 中。Spring 的 url-pattern 的配置慣例是 *.htm,而 Struts 通常是配置成 *.do 或 *.action,它暴露了 web 使用的技術。


73. Spring 中配置了
 <servlet-mapping>
<servlet-name>unmi</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

後,在初始化相應的 DispatcherServlet 時會自動加載 unmi-servlet.xml 文件,它是一個普通的 Spring Bean 配置文件,也是由 WebApplicationContext 加載。其他的 Bean 配置文件需要像通常的做法由 ContextLoaderListener 或 ContextLoaderServlet 來加載。

73. Struts 1.2? 後開始可以在 struts-cnfig.xml 中給 Action 注入簡單屬性,而 Spring 配置 controll 時可以注入所有類型屬性

74. 在 unmi-servlet.xml 中配置的下面這段代碼,Spring 將對請求 URL 是 "/home.html" 結尾的分派給 HomeController 處理,DispatcherServlet 使用的默認處理器映射是 BeanNameUrlHandlerMapping
 <bean name="/home.html" class="com.unmi.HomeController">
<property name="greeting"><value>Welcome to Spring Training</value></property>
</bean>


75. Spring 最簡單的視圖解析器是 InternalResourceViewResoler,如在 unmi-servlet.xml 有下配置
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResoler">
<property name="prefix"><value>/WEB-INF/jsp/</value></proeprty>
<property name="surfix"><value>.jsp/</value></proeprty>
</bean>

那麼,當 HomeController 中 返回 return new ModelAndView("home"); 時將會解析成由視圖 /WEB-INF/jsp/home.jsp 來展示

76. 有三種類型的請求映射控制器,實現的是 HandlerMapping 接口
BeanNameUrlHandlerMapping -- 根據控制器的名字將控制器映射到 URL
SimpleUrlHandlerMapping -- 用上下文配置文件中定義的屬性集合將控制器映射到 URL
CommonsPathMapHandlerMapping -- 使用控制器代碼中的元數據將控制器映射到 URL
DispatcherServlet 缺省映射處理器是 BeanNameUrlHandlerMapping,它將表現層 URL 和控制器名字綁定起來了, Spring 不建議使用這個映射處理器,建議用 SimpleUrlHandlerMapping。可是我覺得用 BeanNameUrlHandlerMapping 挺方便的啊

77. 使用 SimpleUrlHandlerMapping 的配置,需要將系統中用到的 URL 一一邏列出來
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/listCourse.html">listCoursesController</prop>
<prop key="/register.htm">registerStudentController</prop>
</props>
</peroperty>
</bean>


78. 使用 CommonsPathMapHandlerMapping 需要爲 Controller 類註解上 PathMap 屬性爲一個 URL

79. 可用同時配置多映射處理器,通過配置它們實現的 Ordered 接口的 order 屬性,DispatcherServlet 按順序採用哪個映射處理器(責任鏈模式)

80. Spring 提供了豐富的控制器層次,方便根據實際需求選擇實現或繼承那一種控制器

81. 繼承 AbstractController 要覆蓋的方法是 handleRequestInternal(request,response);
new ModelAndView("counrseList","courses",courses) 第一個參數是 view 的邏輯名,第二第三個參數是傳遞給 view 的名稱/數值對

82. 當控制器需要根據參數執行工作時,應該繼承 AbstractCommandController,你的 Controller 中需要覆蓋 handle 方法,並且需要在構造函數中指定命令類,如
public MyController(){
setCommandClass(MyCommand.class);
}

在使用 Command 對象與 Struts 中是一樣的,在 handle 方法中用 MyCommand myCommand = (MyCommand)command,不同的就是 Struts 的 FormBean 是作爲 execute 方法存在,而 Spring 的 command 是作爲成員存在。
命令對象只是一個 POJO,功能相當於 Struts 的 Action,能匹配接受請求中的參數,它不需要在 Spring 的配置文件中配置。留下一個疑問:要是 AbstractCommandController 能在 Spring 的配置文件中注入可能要好些,相當於 Struts 的 Action 的 FormBean 也是在 struts-config.xml 配置給 Action 的
自己試了一下,可以通過配置給 commandClass 一個全限類名字符串註冊 class 屬性,Spring 提供了相應的屬性編輯器
<property name="commandClass">
<value>com.unmi.MyCommand</value>
</property>


83. AbstractFormController 有一個子類 SimpleFormController,它聲明瞭兩個屬性 formView 和 successView,分別對應了在處理請求出現異常和正常時對應的 View 的邏輯名,這兩個屬性需要在配置文件中給配上,在你的 SimpleFormController 類中覆蓋 void doSubmitAction(Object command) throws Exception 將會使用到它們,注意這個方法沒有返回值的。你也可以覆蓋 ModelAndView onSubmit(Ojbect command),向 View 中傳遞數據,return new ModelAndView(getSuccessView(),"student",student); 像 AbstractCommandController 一樣,需要在構造函數中指定 Command 類,可是看那兩個submit 方法,command 再一次通過參數傳入到方法,真的有些多此一舉

84. 驗證表單輸入, 你的驗證類必須實現 org.springframework.validation.Validator 接口,supports()方法幫助判斷驗證器是否適用於指定類,在 validate(Object command, Errors errors) 用 Errors 駁回任何非法數據,如
ValidationUtils.rejectIfEmpty(errors, "login", "required.login" "Login is required");
if(!new Perl5util().match(PHONE_REGEXP,phone){
errors.reject("invalide.phone","Phone number is invalid");
}

最後,你需要把驗證類注入給你的 CommandController 的 validator 屬性
  <property name="validator">
<bean class="com.unmi.MyValidator"/>
</property>


validate 方法會在 AbstractCommandController.handleRequestInternal(request,response)調用,SimpleFormController.onSubmit() 會在調用 doSubmitAction() 之後,把 errors 傳遞給 View。以後要搞清楚錯誤信息要如何顯示出來

85. Spring 提供了 AbstractWizardFormController 來簡化跨越多個頁面處理表單的工作 (嚮導式頁面表單),這是 Struts 所沒有的功能。您只需要覆蓋 processFinish(request,response,command,errors)方法,在最後一個頁面提交後將會被調用處理收集的數據,嚮導中的頁面流程配置到 AbstractWizardFormController 的 pages 屬性,如下
<bean id="feedbackController" class="com.unmi.FeedbackWizardController">
<property name="pages">
<list>
<value>general</value> <!-- 填寫一般性問題 -->
<value>instructor</value> <!-- 填寫導師績效的問題 -->
<value>course</value> <!-- 填寫課程內容和教材問題 -->
<value>facilities</value> <!-- 填寫質量問題 -->
</list>
</property>
</bean>


怎麼分佈顯示嚮導每一步的頁,以及 Controller 中如何處理,待續...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章