欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring开发笔记(3)spring mvc原理及入门

程序员文章站 2024-03-24 19:29:16
...

我们开发的web应用程序是要放到tomcat之类的web容器里运行的,当http请求到来时,tomcat会把请求交给web应用的某个servlet处理。在开发web应用时,自然而然的,我们会想到有多少种http请求需要处理,就编写多少个servlet,然后在web.xml里配置好servlet和http请求uri的对应关系。比如,要处理/add、/query、/delete、/update这4个请求,可以编写AddHttpServlet、QueryHttpServlet、DeleteHttpServlet和UpdateHttpServlet这4个servlet,然后在web.xml文件里配置如下:

<servlet>
   <servlet-name>addServlet</servlet-name>
   <servlet-class>com.myTest.servlet.AddHttpServlet</servlet-class>
</servlet>
<servlet>
   <servlet-name>queryServlet</servlet-name>
   <servlet-class>com.myTest.servlet.QueryHttpServlet</servlet-class>
</servlet>
<servlet>
   <servlet-name>deleteServlet</servlet-name>
   <servlet-class>com.myTest.servlet.DeleteHttpServlet</servlet-class>
</servlet>
<servlet>
   <servlet-name>updateServlet</servlet-name>
   <servlet-class>com.myTest.servlet.UpdateHttpServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>addServlet</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>queyrServlet</servlet-name>
    <url-pattern>/query</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>deleteServlet</servlet-name>
    <url-pattern>/delete</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>updateServlet</servlet-name>
    <url-pattern>/update</url-pattern>
</servlet-mapping>

这样,当用户访问/add时,tomcat就会调用AddHttpServlet来处理;访问/query时,tomcat会调用QueryHttpServlet来处理。以此类推,访问/update、/delete时分别调用UpdateHttpServlet和DeleteHttpServlet来处理。显然,对于每个请求都这样配置一遍是很麻烦的。前面讲了spring的种种好处,那我们在开发web应用时可不可以获得spring带来的便利呢?答案是可以的,spring家族里利用spring容器来帮助我们开发web应用的框架,就是spring mvc。

spring mvc的原理

spring mvc提供了一个DispatcherServlet(类的全名是org.springframework.web.servlet.DispatcherServlet),在web.xml文件里,我们一般都这么配置它:

<servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

也就是说,让DispatcherServlet接管(即处理)所有的http请求。显然DispatcherServlet是spring mvc框架提供的类,我们不能也无法修改它的代码,那么它怎么知道每个具体的http请求该如何处理呢?

所谓mvc,就是model-view-controller的首字母缩写,就是模型-视图-控制器。控制器(controller)就是用来处理具体的http请求的组件。我们需要编写好处理各个http请求的controller类。DispatcherServlet在接收到http请求后,其实它自己不会去处理,而是根据http请求uri的映射规则,将请求转交给相应的controller对象处理。

前面已经学过,spring容器是用来自动创建并管理对象的,显然,controller对象的创建工作也应当交给spring容器来负责(不仅是controller对象,web应用的业务层的serivce对象、数据层的dao对象也应当交给spring容器来创建和管理)。DispatcherServlet在启动时会创建一个spring容器(我们需要告诉spring容器我们的代码在哪个包里,以便spring容器去这个包扫描),spring容器在启动时又会自动创建好所有的controller对象(包括业务层的对象)。DispatcherServlet在初始化时会创建好http请求uri和controller对象的映射关系。当一个http请求到达时,会根据http请求的uri,从spring容器中获取相应的controller对象,将请求交给这个controller对象处理。

示例

下面我们一步步来搭建一个springmvc工程。

1.首先创建一个名为mvc-demo的空的maven工程

spring开发笔记(3)spring mvc原理及入门

2.修改pom.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mytest</groupId>
    <artifactId>mvc-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

工程的打包方式为war,引入spring框架以及springmvc的相关依赖。

3.在工程的src/main路径下创建webapp目录,在webapp目录下创建WEB-INF目录,在WEB-INF目录下创建web.xml文件,这样,打包后的工程就是一个web应用程序了,可以放到tomcat容器中运行:

spring开发笔记(3)spring mvc原理及入门

4.在web.xml文件中添加如下内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.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>

定义了一个DispathcherServlet,<url-patterm>的值为"/",表示它接管所有的http请求。注意,这里给DispathcherServlet提供了一个名为"contextConfigLocation"的初始化参数,其值为"classpath:spring.xml"。前面我们说过,DispathcherServlet在初始化时会创建一个spring容器,这个参数就是用来告诉DispathcherServlet,用spring.xml这个文件来对spring容器进行配置。也就是说,这里的spring容器我们采用的是基于xml文件的配置方式。load-on-startup设置为1,表示让tomcat在启动时就创建好DispathcherServlet的实例。

5.在资源文件目录resources下创建spring.xml文件:

spring开发笔记(3)spring mvc原理及入门

6.在spring.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd" >

    <context:component-scan base-package="com.mytest" />
</beans>

配置文件中其实就是一句话,告诉spring容器去扫描"com.mytest"这个包(我们的代码都位于com.mytest包下)。spring容器在启动时会去扫描“com.mytest”这个包下的所有类,为所有标注了@Bean、@Controller、@Service、@Component之类注解的类创建对象并装配好。

7.接下来,开始着手编写业务代码。我们编写的源代码都保存在src/main/java路径下,在该路径下创建com.mytest包,在该包下创建controller包和service包,然后在controller包下创建HelloController类,service包下创建HelloService接口。在service包下创建impl包,在impl包下创建HelloServiceImpl类:

spring开发笔记(3)spring mvc原理及入门

HelloController的内容如下:

package com.mytest.controller;

import com.mytest.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class HelloController {
    @Autowired
    private HelloService helloService;

    @RequestMapping("hello")
    @ResponseBody
    public String doHello(@RequestParam(value = "name", required = true) String name) {

        return helloService.sayHello(name);
    }
}

@RequestMapping注解定义了Controller类(或方法)和http请求uri的映射关系。@RequestMapping注解既可以标注在类上,也可以标注在方法上。标注在类上,那么就应用到这个类的所有方法上。标注在类上的@RequestMapping提供初步的请求映射信息,标注在方法上的@RequestMapping则提供进一步的请求映射信息。

HelloController类上的@RequestMapping的值是"/",它的doHello方法上的@RequestMapping的值是"hello",因此,当请求"/hello"到来时,DispatherServlet会将请求交给HelloController的doHello方法来处理。前面说DispatherServlet会根据uri的映射关系从spring容器中获取相应的controller对象来处理,更进一步说,uri其实是和controller上的方法建立映射关系的。

doHello方法上标注了@ResponseBody注解,表示将方法返回的字符串作为http response直接返回客户端。doHello方法还有个参数为name,其上加了@RequestParam注解,表示http请求应当携带名为name的参数过来。

HelloService接口的代码如下:

package com.mytest.service;

public interface HelloService {
    String sayHello(String to);
}

HelloServiceImpl类的代码如下:

package com.mytest.service.impl;

import com.mytest.service.HelloService;
import org.springframework.stereotype.Service;

@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String to) {
        return "hello " + to;
    }
}

8.打开工程上的maven命令行,输入mvn clean package,编译所有源代码,并将整个工程打成war包。输出的包文件在工程的target目录下,名称为mvc-test-1.0-SNAPSHOT.war,将这个文件拷贝到tomcat的webapps目录下,改名为mvc-test.war,然后启动tomcat,可以看到tomcat把war包解压到了webapps目录下的mvc-test目录中,mvc-test目录的内容如下:

spring开发笔记(3)spring mvc原理及入门

可以看出,工程里资源文件目录resources下的资源文件,打包后在WEB-INF目录的classes目录下。

9.在浏览器中输入http://localhost:8080/mvc-test/hello?name=tom,可以看到http响应的结果:

spring开发笔记(3)spring mvc原理及入门

至此,我们就搭建了一个最基本的spring mvc应用,不过这个功能非常简单,离实际生产环境的应用还很远。生产环境下的应用,还需要添加许多功能和配置。


相关标签: spring mvc