Spring學習筆記之構建Spring Web應用程式

來源:互聯網
上載者:User
Spring MVC起步 1. Spring MVC 的請求過程

2. 搭建Spring MVC

2.1 用Java來搭建Spring MVC(需要Servlet 3.0環境)

配置DispatcherServlet和ContextLoaderListener

package spittr.config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{    //對應ContextLoaderListener    @Override    protected Class<?>[] getRootConfigClasses() {        return new Class<?>[] { RootConfig.class };    }    //對於DispatcherServlet    @Override    protected Class<?>[] getServletConfigClasses() {        return new Class<?>[] { WebConfig.class };//指定配置類    }    @Override    protected String[] getServletMappings() {        return new String[] { "/" };//將DispatcherServlet映射到"/"    }}

AbstractAnnotationConfigDispatcherServletInitializer剖析
在Servlet3.0環境中,容器會在類路徑中尋找實現javax.servlet.ServletContainerInitializer介面的類,如果發現的話,就會用它來配置Servlet容器。Spring提供了這個介面的實現,名為SpringServletContainerInitializer,這個兩類反過來又會尋找實現WebApplicationInitializer的類並將配置的任務交給它們來完成。Spring3.2引入了一個便利的WebApplicationInitializer基礎實現,也就是AbstractAnnotationConfigDispatcherServletInitializer。因為我們的SpittrWebAppInitializer擴充了AbstractAnnotationConfigDispatcherServletInitializer(同時也實現了WebApplicationInitializer),因此當部署到Servlet3.0容器的時候,容器會自動探索它,並用它來配置Servlet上下文。

AbstractAnnotationConfigDispatcherServletInitializer會同時建立DispatcherServlet和ContextLoaderListener。getRootConfigClasses方法返回的帶有@Configuration註解的類將用來定義ContextLoaderListener應用內容相關的Bean。getServletConfigClasses方法返回的帶有@Configuration註解的類將用來定義DispatcherServlet應用內容相關的Bean。我們希望DispatcherServlet載入包含Web組件的Bean,如控制器、視圖解析器以及處理器映射,而ContextLoaderListener要載入應用中的其他Bean。這些Bean通常是驅動應用後端的中介層和資料層組件。

配置Spring MVC

package spittr.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration @EnableWebMvc //啟用Spring MVC@ComponentScan("spittr.web") //啟用組件掃描public class WebConfig         extends WebMvcConfigurerAdapter{    /**     * 配置JSP視圖解析器     * @return     */    @Bean    public ViewResolver viewResolver(){        InternalResourceViewResolver resolver = new InternalResourceViewResolver();        resolver.setPrefix("/WEB-INF/view/");        resolver.setSuffix(".jsp");        resolver.setExposeContextBeansAsAttributes(true);        return resolver;    }    /**     * 配置靜態資源的處理,要求DispatcherServlet將對靜態資源的請求轉寄到Servlet     * 容器預設的Servlet上,而不是使用DispatcherServlet本身來處理此類請求     */    @Override    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {        configurer.enable();    }}

自訂DispatcherServlet配置
在SpittrWebAppInitializer中我們重寫了三個方法來配置DispatcherServlet,實際上有更多的方法可以進行重載從而實現對DispatcherServlet額外的配置。
方法之一就是customizeRegistration(),在AbstractAnnotationConfigDispatcherServletInitializer將DispatcherServlet註冊到Servlet容器之後,就會調用customizeRegistration(),並將Servlet註冊後得到的Registration.Dynamic傳遞進來。通過重載customizeRegistration()方法,我們可以對DispatcherServlet進行額外的配置。例如設定MultipartConfigElement:

@Override    protected void customizeRegistration(Dynamic registration) {        registration.setMultipartConfig(                new MultipartConfigElement("/tmp/spittr/uploads"));    }

至於這個設定到底是很忙我們將會在Spring上傳中介紹。

添加其他的Servlet和Filter
如果我們想在web容器中註冊其他的Servlet、Filter或者Listener,我們可以通過實現Spring的WebApplicationInitializer(我們前面說過Servlet3.0容器會自動尋找它的實作類別並用來配置servlet容器)。例如注入一個servlet和一個Filter:

import javax.servlet.ServletContext;import javax.servlet.ServletException;import org.springframework.web.WebApplicationInitializer;public class MyServletInitializer implements WebApplicationInitializer{    public void onStartup(ServletContext servletContext) throws ServletException {        //註冊Servlet        javax.servlet.ServletRegistration.Dynamic myServlet =                 servletContext.addServlet("myServlet", MyServlet.class);        myServlet.addMapping("/custom/**");//映射Servlet        javax.servlet.FilterRegistration.Dynamic myFilter =                 servletContext.addFilter("myFilter", MyFilter.class);        myFilter.addMappingForUrlPatterns(null, false, "/custom/**");//添加Filter的映射路徑    }}

如果你只是註冊Filter並將其映射到DispatcherServlet上的話,在AbstractAnnotationConfigDispatcherServletInitializer中還有一種便捷的方法——重載getServletFilters()方法:

@Override    protected Filter[] getServletFilters() {        return new Filter[] { new MyFilter() };    }

2.2 在web.xml中配置Spring MVC:
web.xml:

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5"     xmlns="http://java.sun.com/xml/ns/javaee"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance     http://www.springmodules.org/schema/cache/springmodules-cache.xsd     http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">      <!-- 指定Spring架構上下設定檔的位置,被ContextLoaderListener使用 -->  <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> <servlet>    <servlet-name>dispatcherServlet</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <init-param>        <!-- 指定Spring MVC應用上下文設定檔的位置,如果不在這裡指定,會根據Servlet名字-context尋找設定檔 -->        <param-name>contextConfigLocation</param-name>        <param-value>classpath:dispatcherServlet-context.xml</param-value>    </init-param>    <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>    <servlet-name>dispatcherServlet</servlet-name>    <url-pattern>/</url-pattern> </servlet-mapping></web-app>

applicationContext.xml:

<?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:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <bean id="test" class="spittr.web.Test" />    <context:component-scan base-package="spittr" /></beans>

dispatcherServlet-context.xml:

<?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:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix">/WEB-INF/</property>        <property name="suffix">.jsp</property>    </bean></beans>

2.3 讓web.xml使用Java配置而不是XML配置
也即是說讓Spring MVC在啟動的時候,從帶有@Configuration註解的類上載入配置,我們需要告訴DispatcherServlet和ContextLoaderListener使用AnnotationConfigWebApplicationContext,這是一個WebApplicationContext的實作類別,它會載入Java配置類,而不是使用XML。要實現這種配置,我們只需要設定contextClass上下文參數以及DispatcherServlet的初始化參數。

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5"     xmlns="http://java.sun.com/xml/ns/javaee"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance     http://www.springmodules.org/schema/cache/springmodules-cache.xsd     http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 使用Java配置 -->    <context-param>        <param-name>contextClass</param-name>        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>    </context-param>  <context-param>    <param-name>contextConfigLocation</param-name>    <!-- 指定配置類 -->    <param-value>spittr.config.RootConfig</param-value>  </context-param> <listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet>    <servlet-name>dispatcherServlet</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <!-- 使用Java配置 -->    <init-param>        <param-name>contextClass</param-name>        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>    </init-param>    <init-param>        <param-name>contextConfigLocation</param-name>        <!-- 指定配置類 -->        <param-value>spittr.config.WebConfig</param-value>    </init-param>    <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>    <servlet-name>dispatcherServlet</servlet-name>    <url-pattern>/</url-pattern> </servlet-mapping></web-app>
控制器

預留位置
Spring MVC允許我們在@RequestMapping路徑中添加預留位置。預留位置的名稱要用大括弧(“{”和”}”)括起來。路徑中的其他部分要與所處理的請求完全符合,但是預留位置部分是任意的值。

package spittr.web;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;public class Spittler {    @RequestMapping("/{spittleId}")    public String spittle(            @PathVariable("spittleId") long spittleId){        System.out.println(spittleId);        return "page";    }}

這樣,在請求路徑中,不管預留位置部分的值是什麼都會傳遞到處理器方法的spittleId參數中。
如果@PathVariable中沒有value屬性的話,它會假設預留位置的名稱與方法的參數名相同。

重新導向和前往指定的URL路徑

return "redirect:/spitter/";//重新導向return "forward:/spitter";//前往指定的URL路徑

表單檢驗
從Spring3.0開始,Spring MVC中提供了對Java 校正API的支援。

public class User {    @NotNull    @Size(min=5,max=16)    private String userName; //非空,5-16個字元    @NotNull    @Size(min=6, max=10)    private String password;//非空,6-10個字元}
package spittr.web;import org.springframework.validation.Errors;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.RequestMapping;import spittr.entity.User;public class Spittler {    @RequestMapping("/login")    public String spittle(            @Validated User user,//校正輸入            Errors errors){        if(errors.hasErrors()){            return "registerForm";//如果校正出現錯誤,則重新返回表單。        }        return "redirect:/spitter/";    }}

Errors參數要緊跟在帶有校正註解的參數後面。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.