Spring MVC

---title: 请求处理流程---sequenceDiagram    participant Client as Client (Browser)    participant Dispatcher as Dispatcher Servlet    participant HandlerMapping as Handler Mappings    participant Controller as Controller (Handler)    participant ViewResolver as View Resolvers    participant View as View's    Client->>Dispatcher: 发送请求 (Request)    Dispatcher->>HandlerMapping: 查找 Handler (Request)    HandlerMapping->>Dispatcher: 返回 Controller    Dispatcher->>Controller: 调用 Controller (Request)    Controller->>Dispatcher: 返回 ModelAndView    Dispatcher->>ViewResolver: 查找 View (ViewName)    ViewResolver->>Dispatcher: 返回 View    Dispatcher->>View: 渲染数据 (Model)    View->>Dispatcher: 返回渲染结果    Dispatcher->>Client: 返回响应 (Response)

DispatcherServlet:前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。

HandlerMapping:处理器映射器

HandlerMapping负责根据用户请求找到Handler即处理器,SpringMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

Handler:处理器

它就是我们开发中要编写的 Controller。由DispatcherServlet把用户请求转发到Handler。由Handler对具体的用户请求进行处理。

View Resolver:视图解析器

View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。

View:视图

SpringMVC框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

配置SpringMVC

public class Initalizer extends AbstractAnnotationConfigDispatcherServletInitializer {    @Override    protected Class<?>[] getRootConfigClasses() {        return new Class[0];    }    @Override    protected Class<?>[] getServletConfigClasses() {        return new Class[]{MVCConfig.class};    }    @Override    protected String[] getServletMappings() {        return new String[]{"/"};    }}
// 启用web mvc 以及配置视图解析器@Configuration@EnableWebMvc@ComponentScan("wang.ismy.spring")public class MVCConfig extends WebMvcConfigurationSupport {    @Bean    public ViewResolver viewResolver() {        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();        viewResolver.setPrefix("/WEB-INF/classes/views/");        viewResolver.setSuffix(".jsp");        viewResolver.setViewClass(JstlView.class);        return viewResolver;    }    @Override    protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {        configurer.enable();    }}

使用以上代码可以使用java代码配置dispatcherServlet 原因:servlet3.0中,容器会在类路径查找实现了ServletContainerInitializer的类 Spring提供了该实现,叫做SpringServletContainerInitializer 此类会反过来查找WebApplicationInitializer的实现,而AbstractAnnotationConfigDispatcherServletInitializer就是它的一个实现

控制器编写

@org.springframework.stereotype.Controllerpublic class Controller {    @RequestMapping("/home")    public String hello(){        return "home";    }}

@RequestMapping

public @interface RequestMapping {    // 控制器名称,一般不用    String name() default "";    // 同path    @AliasFor("path")    String[] value() default {};    // 映射路径    @AliasFor("value")    String[] path() default {};    // 请求方法    RequestMethod[] method() default {};    // 限定请求参数条件    String[] params() default {};    // 限定请求头    String[] headers() default {};    String[] consumes() default {};    String[] produces() default {};}

向视图传递数据

@RequestMapping("/home")    public String hello(ModelAndView modelAndView){        modelAndView.addObject("time", LocalDate.now());        return "home";    }

接收请求的输入

表单处理

绑定集合

/user/hello?names=1&names=2

自定义类型转换器

public class LocalDateConvert implements Converter<String, LocalDate> {    @Override    public LocalDate convert(String source) {        return LocalDate.parse(source);    }}
<bean id="converterService" class="org.springframework.context.support.ConversionServiceFactoryBean">        <property name="converters">            <set>                <bean class="wang.ismy.spring.mvc.LocalDateConvert"/>            </set>        </property>    </bean>
public class Person {    @NotBlank     private String username;    @NotBlank     private String password;}
@PostMapping("/form")    public String form(@Valid Person person, Errors errors){        if (errors.hasErrors()){            throw new RuntimeException(errors.getAllErrors().get(0).getDefaultMessage());        }        System.out.println(person);        return "home";    }`

valid api:

批注 2019-06-13 151452

获取servlet api

@RequestMapping("/hello")    public String hello(HttpServletRequest request, HttpServletResponse response){        System.out.println(request+""+response);        return "hello";    }

注解

XML配置

<servlet>    <servlet-name>dispatcher</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <init-param>      <param-name>contextConfigLocation</param-name>      <param-value>classpath:spring-mvc.xml</param-value>    </init-param>  </servlet>  <servlet-mapping>    <servlet-name>dispatcher</servlet-name>    <url-pattern>/</url-pattern>  </servlet-mapping>
<?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: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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">    <context:component-scan base-package="wang.ismy.spring.mvc"/>    <!--视图解析器-->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/views/"/>        <property name="suffix" value=".jsp"/>    </bean>    <!--开启MVC注解支持-->    <mvc:annotation-driven/></beans>