SpringMVC模块

Web开发中的SpringMVC的集成

MVC设计模式

MVC 是一种常见的软件设计模式,用于分离应用程序的不同部分以实现松散耦合和高内聚性。MVC 模式由三个核心组件组成:

  • 模型(Model):表示应用程序的数据和业务逻辑。模型处理应用程序的数据,并根据控制器的指令执行相应的操作。
  • 视图(View):提供模型数据的用户界面。视图通常是模板、HTML 页面、XML 文件或其他格式,可以呈现模型数据给用户。
  • 控制器(Controller):处理用户交互并更新模型和视图。控制器负责接收来自视图的用户输入,对模型进行相应的操作,并更新视图以反映更改。

MVC 模式的优点是可以将代码分离成三个独立的组件,使得应用程序更易于维护和扩展。例如,如果要更改视图的外观,可以修改视图而不影响模型和控制器;如果要更改数据存储方式,可以修改模型而不影响视图和控制器。同时,MVC 模式还有助于降低应用程序中的耦合度,使得各组件更加独立和可重用。

SpringMVC模块

概述:

  • Spring MVC 是非常著名的 Web 应用框架,现在的大多数 Web 项目都采用 Spring MVC。它与 Spring 有着紧密的关系。是 Spring 框架中的模块,专注 Web 应用,能够使用 Spring 提供的强大功能,IOC、AOP等。
  • Spring MVC 框架底层是基于 Servlct 技术。遵循 Servlet 规范,Web 组件 Servlet 、Filter、Listener在 Spring MVC 中都能使用。同时 Spring MVC 也是基于 MVC 架构模式的,职责分离,每个组件只负责自己的功能,组件解耦。
  • Spring Boot 的自动配置按约定编程极大简化,提高了 Web 应用的开发效率。

响应流程

大体流程:请求到控制器(controller),经过业务模型(model)处理后返回响应给视图层。

具体流程:

  • 客户端请求:用户通过浏览器发送 HTTP 请求,所有请求都被 DispatcherServlet 接收。
  • 执行拦截器的 preHandle():如果配置了拦截器,Spring MVC 会首先执行 preHandle() 方法。如果返回 false,请求处理终止;否则,继续处理。
  • 请求映射DispatcherServlet 根据配置的处理器映射器(HandlerMapping)查找与请求 URL 对应的控制器 Controller
  • 调用控制器方法 :找到控制器后,DispatcherServlet 将使用 HandlerAdapter 来调用 Controller 的处理方法。转发给对应的控制器方法进行处理。控制器方法处理业务逻辑后,通常返回一个 ModelAndView 对象,包含数据模型和视图名称。
  • 执行拦截器的 postHandle():如果返回视图,拦截器的 postHandle() 方法会在视图渲染之前执行。对于 JSON 响应,该方法仍然会执行。
  • 视图解析DispatcherServlet 根据控制器返回的视图名称,使用视图解析器( ViewResolver )将逻辑视图名称解析为实际的视图
  • 视图渲染返回:视图渲染引擎根据数据模型渲染视图,并将生成的 HTML 响应返回给客户端

结构组件

控制器controller

控制器是一种由 Spring 管理的 Bean 对象,赋予角色是“控制器”。

作用:处理请求,接收浏览器发送过来的参数,将数据或视图应答给浏览器或者客户端 App等。

具体实现:一个Java类,使用@Controller或@RestController

提示

@Controller@RestController 注解的区别:

  • @RestController 包含了 @Controller 的功能,同时加入了 @ResponseBody 的注解。
  • 表示当前控制器类中的方法,都会默认加入 @ResponseBody 的功能。方法的返回值是数据可以通过 HttpServletResponse 输出给浏览器。

接收请求

  • @RequestMapping :用于将 Web 请求映射到控制器类的方法。此方法处理请求。可用作在类上或方法上。在类上和方法上同时使用。

    1
    2
    3
    
     @RequestMapping(value = "/updateProduct",method = RequestMethod.POST)
        public Result<String> updateProduct(@RequestParam MultipartFile file, @RequestParam String dname,
                                            @RequestParam String tname, @RequestParam String content,@RequestParam String olddname)
    
    • Value:别名 path 表示请求的 URI,在类和方法上同时使用 value,方法上的继承类上的 value。
    • method:请求方式,支持 GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE。值为:RequestMethod[] method(),RquestMethod 是 enum 类型。
  • 快捷注解:

    • @GetMapping: 表示 get 请求方式的@RequestMapping
    • @PostMapping:表示 post 请求方式的@RequestMapping
    • @PutMapping:表示 put 请求方式的@RequestMapping
    • @DeleteMapping: 表示 delete 请求方式的@RequestMapping

接收请求参数

  • @RequestParam:把请求中的指定名称的参数传递给控制器中的形参赋值

    • value属性值指定请求中的参数
    • required 属性指定请求中的参数是否必须,默认为 true ,如果加上 required=false,没对应上则不会报错,而是获取值为 null。
    • 如果参数前不写@RequestParam(xxx)的话,那么就前端可以有可以没有对应的参数名字都行,如果有参数名的话,那么就会自动匹配;没有的话,请求也能正确发送。
  • HttpServletRequest对象
    • 使用 HttpServletRequest 对象接收参数,request.getParameter("XXX")获取对应的值,这是原始的 JavaWeb 中的方式
  • @RequestBody:主要用来接收前端传递给后端的json字符串中的数据的(通常json字符串放在请求体中)

    • GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
    • 在后端的同一个接收方法里,@RequestBody@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
    • 如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性
  • @RequestHeader:从请求头中获取某些值

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestHeader;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class MyController {
    
        @GetMapping("/greet")
        public String greet(@RequestHeader("User-Agent") String userAgent) {
            return "Hello! You are using " + userAgent;
        }
    }
    

返回值

  • 不使用 @ResponseBody的 String 返回值,返回的是一个页面视图
  • 使用 @ResponseBody的 String 返回值,返回的是一个JSON数据
  • 返回ModelAndView ,返回的是一个视图其中包含数据。(最后数据都是放到 Request 中的)
  • 返回自定义的对像,默认的返回格式是json字符串(有jackson工具)
  • 返回 Map,默认的返回格式是json字符串(有jackson工具)
  • 返回ResponseEntity:包含数据和自定义的HttpStatus Code。(默认转为json格式的字符串)

模型 Model

  • 在许多实际项目需求中,后台要从控制层直接返回前端所需要的数据,这时 Model 大家族就派上用场了。
  • Model Spring MVC 中的 ”M“,是用来传输数据的。从控制层直接返回数据给前端。内置的 JSP,模板技术能够展现 Model 中存储的数据。
  • Model 可以是承载数据的,也可以是处理具体业务的类,这些都是指 Spring MVC 中的Model。

视图 View

  • Spring MVC 中的 View(视图)用于展示数据的,视图技术的使用是可插拔的。无论选择使用 thymleaf、jsp 还是其他技术,classpath 有 jar 就能使用视图了。开发者主要就是更改配置。SpringBoot3 不推荐使用 FreeMarker、JSP 这些了。建议使用 Thymeleaf。

SpringMVC的核心组件

  • DispatcherServlet核心的中央处理器,负责接收请求、分发,并给予客户端响应。

    • 当客户端发送请求时,DispatcherServlet 会先接收请求。
    • 然后,它会根据请求 URL 通过 HandlerMapping 找到合适的处理器(Controller)。
    • 处理完请求后,它会根据 ViewResolver 找到对应的视图,将处理结果发送回客户端。
  • HandlerMapping处理器映射器,根据 URL 去匹配查找能处理的 Handler ,并会将请求涉及到的拦截器和 Handler 一起封装。

  • HandlerAdapter处理器适配器,根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler

  • Handler请求处理器,处理实际请求的处理器。

    • 接收来自 DispatcherServlet 的请求,处理业务逻辑,并将处理结果返回给视图层。
  • ViewResolver视图解析器,根据 Handler 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet 响应客户端

    • 根据控制器返回的视图名称找到对应的视图文件
  • ModelAndView :控制器返回的对象,包含模型数据和视图名称。模型部分包含业务数据,视图部分指定渲染该数据的视图

  • HandlerInterceptor :在请求处理的各个阶段(如控制器方法执行前后)进行拦截。它可以用于实现日志记录、权限验证等功能。模板。

SpringBoot框架中对SpringMVC框架的集成

  • 自动配置:SpringBoot会自动配置一个嵌入式的Servlet容器(如Tomcat),并为我们提供默认的SpringMVC配置。这样我们无需手动配置Servlet容器和SpringMVC,只需添加相应的依赖即可快速搭建一个Web应用。
  • 视图解析器:SpringBoot默认使用Thymeleaf作为视图解析器,如果需要更换其他视图解析器,可以在pom.xml中修改对应的依赖。
  • 静态资源处理:SpringBoot默认会处理静态资源(如HTML、CSS、JavaScript等),并将其放在项目的/static或/public目录下。如果需要自定义静态资源的处理方式,可以通过编写一个类实现WebMvcConfigurer接口,并重写addResourceHandlers方法来实现。
  • 拦截器:SpringBoot支持自定义拦截器,可以通过实现HandlerInterceptor接口来创建拦截器,同时编写一个类实现WebMvcConfigurer接口,并重写addInterceptors方法来实现。
  • 异常处理:SpringBoot默认使用WhitelabelErrorView来处理异常,如果需要自定义异常处理方式,可以通过编写一个类实现ErrorController接口,并重写errorHtml方法来实现。
  • 参数绑定:SpringBoot支持多种参数绑定方式,如@RequestParam、@PathVariable、@RequestBody等。如果需要自定义参数绑定方式,可以通过编写一个类实现MethodArgumentResolver接口,并重写resolveArgument方法来实现。
  • 跨域支持:SpringBoot默认支持CORS跨域请求,如果需要自定义跨域配置,可以通过编写一个类实现WebMvcConfigurer接口,并重写addCorsMappings方法来实现。

Spring Boot中配置Spring MVC

配置方法

因为Spring Boot自动装配机制的存在,一般来说我们不需要对Spring MVC进行配置,如果要进行特别定制化的配置,Spring Boot也支持配置文件或者编写代码的两种方式来进行配置。

方法一:修改application.xml

可以通过修改application.xml的spring.mvc属性来修改SpringBoot对SpringMVC的默认配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
spring:
	mvc:
		# 启用Spring MVC
		enabled: true
		
		# 配置静态资源路径
		static-path-pattern: /static/**
		static-locations: classpath:/static/

		# 配置视图解析器
		view.prefix: /WEB-INF/views/
		view.suffix: .jsp
		
		# 配置拦截器
		interceptor:
			exclude-path-patterns: /login,/logout
			include-path-patterns: /admin/**

	# 配置HTTP缓存
	resources:
		cache:
			period: 3600

	servlet:
		# 配置文件上传
		multipart:
			max-file-size: 10MB
			max-request-size: 10MB
		# 配置会话管理
			session:
				timeout: 1800
				cookie.max-age: 1800

	# 配置JSON序列化
	jackson:
		serialization:
			indent_output: true
		date-format: yyyy-MM-dd HH:mm:ss

	# 配置异常处理
	error:
		whitelabel:
			enabled: false

方法二:编写一个被注解@WebMvcConfiguration修饰的Java配置类

WebMvcConfigurer 接口是Spring提供的一个用于自定义Spring MVC配置的接口,主要提供了WebMvcConfigurer接口是Spring提供的一个用于自定义Spring MVC配置的接口,主要提供了多个回调方法,包括添加或修改Spring MVC的配置,如添加拦截器,自定义消息转换器等。具体来说,WebMvcConfigurer 接口的主要方法包括:

  • configurePathMatch(S):此方法用于配置路由请求规则。
  • configureContentNegotiation(S):该方法用于内容协商配置。
  • configureAsyncSupport(S):该方法用于异步支持配置。
  • configureDefaultServletHandling(S):该方法用于配置默认静态资源处理器。
  • addFormatters(S):此方法用于注册自定义转化器。
  • addInterceptors(S):此方法用于拦截器配置。
  • addResourceHandlers(S):此方法用于资源处理。
  • addCorsMappings(S):此方法用于CORS配置。

在使用时,只需要实现WebMvcConfigurer接口,重写上述的方法即可完成自定义配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
 
    // 配置视图解析器
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        registry.viewResolver(resolver);
    }
 
    // 配置静态资源
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }
 
    // 配置拦截器
    @Autowired
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }
 
    // 配置消息转换器
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        converters.add(converter);
    }
 
    // 配置异常处理器
    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = Exception.class)
        public ModelAndView handleException(HttpServletRequest req, Exception e) {
            ModelAndView mav = new ModelAndView();
            mav.addObject("exception", e);
            mav.addObject("url", req.getRequestURL());
            mav.setViewName("error");
            return mav;
        }
    }
 
    // 配置全局跨域资源共享(CORS)
    @Override
    public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/user/*") // 映射服务器中那些http接口运行跨域访问
		.allowedOrigins("http://localhost:8081") // 配置哪些来源有权限跨域
		.allowedMethods("GET","POST","DELETE","PUT"); // 配置运行跨域访问的请求方法
    }
 
    // 配置文件上传
    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setMaxUploadSize(10485760);
        resolver.setMaxInMemorySize(4096);
        return resolver;
    }
 
    // 配置请求缓存
    @Bean
    public KeyGenerator keyGenerator() {
        return new DefaultKeyGenerator();
    }
 
    @Bean
    public RequestCache requestCache() {
        return new HttpSessionRequestCache();
    }
 
    // 配置视图控制器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/login").setViewName("login");
    }
}

提示

  • 使用Springboot框架对SpringMVC的默认设置:直接编写控制器逻辑

  • 手动设置SpringMVC的部分功能,定义MVC的底层组件:@Configuration+配置WebMvcConfiguration,不要使用@EnableWebMvc

  • 手动设置SpringMVC的所有功能:@Configuration+配置WebMvcConfiguration+@EnableMvc

    使用 @EnableWebMvc 会完全覆盖 SpringBoot 对 SpringMVC 的自动配置,因此如果使用了 @EnableWebMvc,就需要自己配置 Spring MVC 的全部内容,包括视图解析器、资源处理、异常处理等。通常情况下,只有在需要非常精细的控制 Spring MVC 配置时才会使用 @EnableWebMvc。

그 경기 끝나고 좀 멍하기 있었는데 여러분 이제 살면서 여러가
使用 Hugo 构建
主题 StackJimmy 设计