Spring学习笔记之构建Spring Web应用程序

来源:互联网 发布:各种淘宝助理版本下载 编辑:程序博客网 时间:2024/05/22 01:10

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参数要紧跟在带有校验注解的参数后面。

1 0
原创粉丝点击