SpringMVC概述

一、了解

  Spring Web MVC是一种基于java,并实现了WebMVC设计模式的请求驱动类型的轻量级Web框架(基于请求驱动指的是就是使用请求-相应模型)。

  该框架也是用了MVC架构模式的思想,将web层进行职责解耦。它的目的就是帮助我们简化开发。

  Spring Web MVC的前端控制器为DispatcherServlet,其应用控制器可以拆解为:

    A、(Handler Mapping)处理器管理;

    B、视图解析器(View Resolver)进行视图管理;

    C、页面控制器/动作/处理器为Controller接口

 

二、流程说明

  在请求离开浏览器时,会带有用户所请求内容的信息,至少会包含请求的URL。但是还可能带有其他的信息,例如用户提交的表单信息。

  1、请求的第一站是Spring的DispatcherServlet。与大多数基于Java的Web框架一样,SpringMVC所有的请求都会通过一个前端控制器(front controller)Servlet。前端控制器是常用的Web应用程序模式,在这里一个单例的Servlet将请求委托给应用程序的其他组件来执行实际的处理。在Spring MVC中DispatcherServlet就是前端控制器。(DispatcherServlet的任务就是将请求送给SpringMVC控制器controller),控制器是一个用于处理请求的Spring组件。

  2、请求的第二站是处理器映射,在典型的应用程序中可能会有多个控制器,DispatcherServlet需要知道应该请求发送给哪个控制器。所以DispatcherServlet以查询一个或多个处理器映射(handler mapping)来确定请求的下一站在哪里。处理器映射会根据请求所携带的URL信息来进行决策。一旦选择了合适的控制器,DispatcherServlet会将请求发送给选中的控制器。

  3、到了控制器,请求会卸下其负载(用户提交的信息)并耐心等待控制器处理这些信息。(实际上,设计良好的控制其本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理。)

    控制器在完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示。这些信息被称为模型(model)

    不过仅仅给用户返回原始信息是不够的,这些信息需要以用户友好的方式进行格式化,一般会是HTML。所以信息需要发送一个视图(view),通常是一个JSP  

  4、控制器所做的最后一件事就是将模型数据打包,并且标示出用于渲染输出的视图名。它接下来会将请求连同模型和视图名发送会DispatcherServlet。这样控制器就不会与特定的视图相耦合,传递给DispatcherServlet的视图名并不直接表示某个特定的JSP。实际上,它甚至并不能确定视图就是JSP。相反,它仅仅传递了一个逻辑名称,这个名字将会用来查找产生结果的真正视图。

  5、DispatcherServlet将会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现,它可能是JSP也可能不是。既然DispatcherServlet已经知道由哪个视图渲染结果,那请求的任务基本上也就完成了。它的最后一站是视图的实现。

  6、在这里它交付了模型数据。请求的任务就完成了。

  7、视图将使用模型数据渲染输出,这个输出会通过相应对象response传递给客户端。

 

三、配置SpringMVC的例子

  在配置SpringMVC前需要配置gradle,build.gradle如下:

group 'B10'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile group: 'org.springframework', name: 'spring-webmvc', version: '5.0.0.RELEASE'
    compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
    compile group: 'javax.servlet', name: 'jstl', version: '1.2'
}

  按照之前的方法,servlet的配置信息会放在web.xml下,而现在,我们可以通过继承AbstractAnnotationConfigDispatcherServletInitializer类而生成的子类WebInitializer,而这个类就是所谓的DispatcherServlet,所以WebInitializer如下:

  

package com.zxc.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

/**
 * Created by Administrator on 2018/4/2.
 */
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};//注册 配置文件
    }

    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter=new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        filter.setForceEncoding(true);
        return new Filter[]{filter};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

}

  我们书写DispatcherServlet的时候,需要重写三个方法:

    1、getServletMappings():它会将一个或多个路径映射到DispatcherServlet上。在本例中,它映射的是“/”,这表示它会是引用的默认Servlet。它会处理进入引用的所有请求。

    2、getServletConfigClasses(),方法返回的带有@Configuration注解的类将会用来定义DispatcherServlet引用上下文中的bean。

    3、getRootConfigClasses()方法返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean。

    如果愿意的话可以web.xml和上面的DispatcherServlet一起写,但没什么更多的用处,因为重复。

 

  我们需要配置DispatcherServlet,上面的getServletConfigClasses()方法可以读取到其配置文件webConfig.xml,代码如下:

package com.zxc.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.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * Created by Administrator on 2018/4/2.
 */

@Configuration
@EnableWebMvc
@ComponentScan("com.weikun")
public class WebConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ViewResolver viewResolver(){//告诉SpringMVC 他的V层在哪里
        InternalResourceViewResolver vr=new InternalResourceViewResolver();
        vr.setPrefix("/WEB-INF/view/");
        vr.setSuffix(".jsp");
        return vr;
}

    @Override//允许spring mvc控制器对静态资源进行放行。
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // TODO Auto-generated method stub
        super.addResourceHandlers(registry);
    }
}

@EnableWebMvc:启用SpringMVC。

@ComponentScan:启用组件扫描,告诉控制器扫描哪里

viewResolver()方法用来配置JSP视图解释器,在查找的时候它会在视图名称上加上特定的前后缀。(注意方法上需要加@Bean)

 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

上面这个方法的作用是配置静态资源处理,我们要求DispatcherServlet将对静态资源的请求转发到Servlet容器中默认的Servlet上,而不是亲自来处理请求。

  

配置完DispatcherServlet后,需要我们写具体的一个控制器:

package com.zxc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;
@Controller
public class MyController {
    @RequestMapping("/hello")
    public String hello(){
        return "success";
    }
}

请求为/hello时候,映射到这里。

前端页面主要内容:

<a href="/hello">你好</a>

 

四、Spring MVC的注解写法

  在Spring2.5版本之前我们通过实现Controller接口或其实现来定义我们的处理器类,现在我们使用注解式的控制器。通过@Controller和@RequestMapping注解定义我们的处理器类。并且提供了一组强大的注解:

  1、@Controller:用于标识是处理器类

  2、@RequestMapping:请求到处理器功能方法的映射规则;

  3、@RequestParam:请求参数到处理器功能处理方法的方法参数上绑定。

  4、@ModelAttribute:请求参数到命令对象的绑定;

  5、@SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;

  6、窄化请求映射:2是对1的窄化;当我们在不同的控制器中有多个针对于/hello的映射,这样,前端就不知道该映射到哪一个,这样,现在类上进行一次映射规则设定,再在具体方法上进行窄化规则。

 

  7、URL路径映射方式一:

    普通的URL路径映射:

       @RequestMapping(value={"/test1","/user/create"}):多个URL路径可以映射到同一个控制器的功能处理方式(/test1和/user/create都会映射到这个控制器类下)

     

    URI模板模式映射:

       @RequestMapping(value="/users/{userId}"):其中{xxx}为占位符,请求的URL可以是“/users/123456"或“/user/abcd”,

       @RequestMapping(value="/users/{userId}/create"):这样也是可以的,请求的URL可以是“/users/123/create”.

       @ResquestMapping(value="/users/{userId}/topics/{topicId}"):这样也是可以的,请求的URL可以是“/user/123/topics/123”

    

    URL路径映射-ANT风格

  

 @RequestMapping(value = "/ok2/{username}/{pwd}")
    public String ok2(@PathVariable String username,@PathVariable String pwd){

        System.out.println(username);
        System.out.println(pwd);
        return "success";
    }

 

    URL路径映射-正则风格

    从Spring3.0开始支持正则表达式风格的URL路径映射,格式为{变量名:正则表达式}

 @RequestMapping(value = "/ok3/{username:\\d+}-{pwd:\\d+}")
    public String ok3(@PathVariable String username,@PathVariable String pwd){
        System.out.println(username);
        System.out.println(pwd);
        return "success";
    }

 

 

  8、 @RequestMapping(value = "/ok1",method = {RequestMethod.POST})

  这样可以限定映射的方式只为post

        

posted @ 2018-04-06 20:55  彩电  阅读(202)  评论(0编辑  收藏  举报