首页 > 代码库 > spring in action 4 5.1 Getting started with Spring MVC

spring in action 4 5.1 Getting started with Spring MVC

5.1.1 Following the life of a request

Every time a user clicks a link or submits a form in their web browser, a request goes to
work. A request’s job description is that of a courier. Just like a postal carrier or a
FedEx delivery person, a request lives to carry information from one place to another.
The request is a busy creature. From the time it leaves the browser until it returns
with a response, it makes several stops, each time dropping off a bit of information
and picking up some more. Figure 5.1 shows all the stops the request makes as it travels through Spring MVC

每次用户在浏览器上点击一个链接或者提交一个表单时,请求就开始工作了.请求的工作内容就跟邮递员或者联邦快递员一样,他们把信息从一个地方送到另一个地方.从离开浏览器开始到返回一个响应为止,请求要停留好几次,每次都留下一些信息然后带走更多信息.图5.1显示一个请求在spring mvc框架中传输时所做的停留.

技术分享

The first stop in the request’s travels is at Spring’s DispatcherServlet. Like most Javabased web frameworks, Spring MVC funnels requests through a single front controller
servlet. A front controller is a common web application pattern where a single servlet
delegates responsibility for a request to other components of an application to perform actual processing. In the case of Spring MVC, DispatcherServlet is the front
controller.

请求的第一站是spring的DispatchServlet.和大多数基于java的Web框架一样,spring mvc也是通过一个前端控制器分发请求.前端控制器就是一个普通的web应用模型,在这里有一个sevlet负责把请求委派给应用中其它的组件,组件将会根据请求的信息执行相应的操作.在spring mvc框架中,DispatchServlet就是前端控制器.

The DispatcherServlet’s job is to send the request on to a Spring MVC controller.
A controller is a Spring component that processes the request. But a typical application
may have several controllers, and DispatcherServlet needs some help deciding
which controller to send the request to. So the DispatcherServlet consults one or
more handler mappings to figure out where the request’s next stop will be. The
handler mapping pays particular attention to the URL carried by the request when
making its decision.

Dispatch的工作是将请求发送给相应的spring mvc控制器.控制器是spring mvc框架中负责处理请求的组件.通常应用中都有很多控制器,dispatcher需要判断应该把请求发送给哪个控制器,是如何判断的呢?dispatcherservet首先查看handler mappings(第二步),

5.1.2 Setting up Spring MVC

Based on figure 5.1, it looks like there are a lot of moving parts to be configured. Fortunately, thanks to some advancements in the most recent versions of Spring, it’s easy
to get started with Spring MVC. For now, you’ll take the simplest approach to configuring Spring MVC: you’ll do just enough configuring to be able to run the controllers
you create. In chapter 7, we’ll look at some additional setup options.

在图5.1中,貌似需要配置好多信息.不过幸运的是,多亏了spring最近版本的改进,启动一个spring mvc项目并不需要花费太多精力.现在,你将要用最简单的方式配置一个spring mvc项目.只需要配置能运行控制器的必要步骤即可.等到了第7章,再详细讲解其它的配置.

CONFIGURING DISPATCHERSERVLET
DispatcherServlet is the centerpiece of Spring MVC. It’s where the request first hits
the framework, and it’s responsible for routing the request through all the other
components.

DispatcherServlet 是spring mvc框架的核心.是请求遇到的第一个spring mvc组件,它负责引导请求在各个组件之间的流通.

Historically, servlets like DispatcherServlet have been configured in a web.xml
file that’s carried in the web application’s WAR file. Certainly that’s one option for configuring DispatcherServlet. But thanks to recent advances in the Servlet 3 specification and in Spring 3.1, it’s not the only option. And it’s not the option we’ll go with in
this chapter.

在以往,配置dispatchservlet必须在web.xml文件里配置一个servlet,不过在servlet 3 规范和spring 3.1版本中,还有其它的方式实现dispatchservlet.

Instead of a web.xml file, you’re going to use Java to configure DispatcherServlet
in the servlet container. The following listing shows the Java class you’ll need.

与在web.xml中配置不同,本章将在java文件配置DispatcherServlet.

Listing 5.1 Configuring DispatcherServlet
package spittr.config;
import org.springframework.web.servlet.support.
AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
}

To understand how listing 5.1 works, it’s probably sufficient to know that any class
that extends AbstractAnnotationConfigDispatcherServletInitializer will automatically be used to configure DispatcherServlet and the Spring application context in the application’s servlet context.

要理解代码5.1的作用,你需要知道在应用的servlet容器内,任何继承 AbstractAnnotationConfigDispatcherServletInitializer 的类将被框架自动用于配置DispatcherServlet 以及spring 应用上下文.

AbstractAnnotationConfigDispatcherServletInitializer exposed
If you insist on the more detailed explanation, here it is. In a Servlet 3.0 environment,
the container looks for any classes in the classpath that implement the javax.servlet
.ServletContainerInitializer interface; if any are found, they’re used to configure the servlet container.
Spring supplies an implementation of that interface called SpringServletContainerInitializer that, in turn, seeks out any classes that implement WebApplicationInitializer and delegates to them for configuration. Spring 3.2
introduced a convenient base implementation of WebApplicationInitializer
called AbstractAnnotationConfigDispatcherServletInitializer. Because
your SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer (and thus implements WebApplicationInitializer), it will
be automatically discovered when deployed in a Servlet 3.0 container and be used to
configure the servlet context.

在servlet3.0的环境中,容器将在类路径下查找任何实现了javax.servlet.ServletContainerInitializer的接口,如果找到了,这些接口就将用于配置servlet容器.

spring提供了这个接口的实现,即SpringServletContainerInitializer,这样,容器将查找任何实现了WebApplicationInitializer的类,然后使用这些类来配置servlet容器.spring 3.2引入了一个简便的WebApplicationInitializer实现,名为AbstractAnnotationConfigDispatcherServletInitializer,因为代码5.1中的SpittrWebAppInitializer类继承了AbstractAnnotationConfigDispatcherServletInitializer(当然也就继承了WebApplicationInitializer
),所以SpittrWebAppInitializer将会在部署到servlet3.0容器后,被容器自动发现,用于配置servlet上下文.

Even though its name is extremely long, AbstractAnnotationConfigDispatcherServletInitializer is a snap to use. Looking at listing 5.1, you can see that SpittrWebAppInitializer overrides three methods.

别看AbstractAnnotationConfigDispatcherServletInitializer 名字挺长的,使用起来其实挺简单的.从代码5.1中我们可以看到SpittrWebAppInitializer重写了三个方法.

The first method, getServletMappings(), identifies one or more paths that DispatcherServlet will be mapped to. In this case, it’s mapped to /, indicating that it will be the application’s default servlet. It will handle all requests coming into the application.

第一个方法,名为getServletMappings(),标明了DispatcherServlet映射的路径.在本例中,DispatcherServlet映射的是"/",表示它是应用的默认servlet,它将处理所有发向该应用的请求.

In order to understand the other two methods, you must first understand the relationship between DispatcherServlet and a servlet listener known as ContextLoaderListener
为了理解其它两个方法,你需要先理解DispatcherServlet 和 名为ContextLoaderListener的servlet监控器之间的关系.

A TALE OF TWO APPLICATION CONTEXTS

When DispatcherServlet starts up, it creates a Spring application context and starts
loading it with beans declared in the configuration files or classes that it’s given. With
the getServletConfigClasses() method in listing 5.1, you’ve asked that DispatcherServlet load its application context with beans defined in the WebConfig configuration class (using Java configuration).

DispatcherServlet后,它将创建一个spring应用上下文并开始加载声明在配置文件或者给定类里的bean.DispatcherServlet就是加载代码5.1中的getServletConfigClasses方法返回值里对应的bean,在本例中,这些bean是定义在java文件里的.

But in Spring web applications, there’s often another application context. This
other application context is created by ContextLoaderListener.

但是在spring web 应用中,还有另一种应用上下文.这种应用上下文是由ContextLoaderListener创建的.

Whereas DispatcherServlet is expected to load beans containing web components
such as controllers, view resolvers, and handler mappings, ContextLoaderListener is
expected to load the other beans in your application. These beans are typically the
middle-tier and data-tier components that drive the back end of the application.

DispatcherServlet要加载web组件相关的bean,比如说控制器/视图/URL映射等.而ContextLoaderListener负责加载其它类型的Bean.ContextLoaderListener加载的类主要属于中间层和数据层的组件,就是这些组件驱动着应用的后端.

Under the covers, AbstractAnnotationConfigDispatcherServletInitializer creates both a DispatcherServlet and a ContextLoaderListener. The @Configuration
classes returned from getServletConfigClasses() will define beans for DispatcherServlet’s application context. Meanwhile, the @Configuration class’s returned getRootConfigClasses() will be used to configure the application context created by
ContextLoaderListener.

AbstractAnnotationConfigDispatcherServletInitializer会创建一个DispatcherServlet和一个ContextLoaderListener.方法getServletConfigClasses返回的所有被注解@Configuration修饰的类即组成了DispatcherServlet创建的应用上下文,同时,方法getRootConfigClasses返回的所有被注解Configuration 修饰的类则组成了由ContextLoaderListener创建的的应用上下文.

In this case, your root configuration is defined in RootConfig, whereas DispatcherServlet’s configuration is declared in WebConfig. You’ll see what those two configuration classes look like in a moment.

在本例中,root配置信息定义在RootConfig类中,而DispatcherServlet的配置则声明在WebConfig中,一会你就会看到这两个配置类包含的内容了.

It’s important to realize that configuring DispatcherServlet via AbstractAnnotationConfigDispatcherServletInitializer is an alternative to the traditional web.xml file. Although you can include a web.xml file alongside a subclass
of AbstractAnnotationConfigDispatcherServletInitializer if you like, it’s not
necessary.

AbstractAnnotationConfigDispatcherServletInitializer 是除web.xml之外的另一种配置应用信息的方式.虽然你可以在应用中包含web.xml文件作为AbstractAnnotationConfigDispatcherServletInitializer 的子集,但是这种做法真的没有必要.

The only gotcha with configuring DispatcherServlet in this way, as opposed to in
a web.xml file, is that it will only work when deploying to a server that supports
Servlet 3.0, such as Apache Tomcat 7 or higher. The Servlet 3.0 specification has been
final since December 2009, and the odds are good that you’ll be deploying your applications to a servlet container that supports Servlet 3.0.

AbstractAnnotationConfigDispatcherServletInitializer只能配置在支持servlet3.0的环境里,比如tomcat7及其以上版本,servlet3.0规范是在2009看12月定稿的,至此,你就可以把应用部署在支持servlet3.0的servlet容器里了.

If you’re not yet working with a Servlet 3.0-capable server, then configuring
DispatcherServlet in a subclass of AbstractAnnotationConfigDispatcherServletInitializer won’t work for you. You’ll have no choice but to configure DispatcherServlet in web.xml. We’ll look at web.xml and other configuration options in chapter 7. For now, though, let’s look at WebConfig and RootConfig, the two configuration classes referred to in listing 5.1, and see how to enable Spring MVC.

如果你开发的环境还不支持servlet3.0,那么你是不能通过AbstractAnnotationConfigDispatcherServletInitializer的子类配置DispatcherServlet 的.你没有其它的选择,只能在web.xml中配置DispatcherServlet .我们将在第7章中学习web.xml及其它的配置选项.现在我们先研究下代码5.1中的WebConfig and RootConfig,看看如何通过它们来使用spring mvc.

ENABLING SPRING MVC 使用spring mvc

Just as there are several ways of configuring DispatcherServlet, there’s more than
one way to enable Spring MVC components. Historically, Spring has been configured
using XML, and there’s an <mvc:annotation-driven> element that you can use to
enable annotation-driven Spring MVC.
We’ll talk about <mvc:annotation-driven>, among other Spring MVC configuration options, in chapter 7. But for now, you’ll keep your Spring MVC setup simple and
Java-based.
The very simplest Spring MVC configuration you can create is a class annotated
with @EnableWebMvc:

配置DispatcherServlet的方法不只一种,配置Spring MVC的方法当然也不只一种.在此之前,我们用xml配置spring,使用<mvc:annotation-driven>这个元素激活spring mvc中的注解.

我们以后再讨论<mvc:annotation-driven>这个元素.现在我们基于java配置一个简单但功能齐全的spring mvc.

package spittr.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@EnableWebMvc
public class WebConfig {
}



本文出自 “梦里不知身是客” 博客,转载请与作者联系!

spring in action 4 5.1 Getting started with Spring MVC