Spring基础分析10-Spring MVC架构模式详解

大家好,今天和大家一起分享一下SpringMVC架构模式~

Spring MVC(Model-View-Controller)是Spring框架的一部分,专为简化Web应用程序开发而设计。它基于MVC设计模式,将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种分层结构有助于实现关注点分离,提高代码的可维护性和重用性。

  • Model:负责管理应用程序的数据逻辑。通常包括业务对象和服务层。
  • View:负责展示数据给用户,并收集用户的输入。
  • Controller:作为Model和View之间的桥梁,处理用户请求,调用相应的业务逻辑,并返回适当的View。

核心组件

  1. DispatcherServlet:作为前端控制器,接收所有的HTTP请求并将其分发到合适的处理器。
  2. HandlerMapping:定义了如何将请求映射到具体的处理器。Spring提供了多种内置的HandlerMapping实现。
  3. Controller:处理器接口,用于处理特定类型的请求。可以是任何实现了Controller接口的对象,或者使用注解如@Controller和@RequestMapping来标识。
  4. ViewResolver:决定使用哪个视图解析器来解析逻辑视图名称。
  5. ModelAndView:封装了模型数据和视图信息。
  6. ExceptionHandler:用于处理异常,可以通过@ExceptionHandler注解指定。

配置Spring MVC

在Spring 4.x及以上版本中,推荐使用Java配置代替XML配置。下面是一个简单的Spring MVC Java配置示例:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example")
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

    // 其他配置...
}

为了使这个配置生效,还需要在web.xml中注册DispatcherServlet:
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.example.config.WebConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

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

创建控制器

接下来,我们创建一个简单的控制器,该控制器响应根路径的GET请求:

@Controller
@RequestMapping("/")
public class HomeController {

    @GetMapping
    public String home(Model model) {
        model.addAttribute("message", "Hello, World!");
        return "home"; // 返回逻辑视图名
    }
}

在这个例子中,home方法接受一个Model参数用来向视图传递数据,并返回一个字符串"home"作为逻辑视图名,这将由ViewResolver解析为实际的视图资源。

视图层

视图层通常是由JSP、Thymeleaf、Freemarker等模板引擎生成的HTML页面。对于上面的例子,我们假设使用的是JSP,那么/WEB-INF/views/home.jsp可能看起来像这样:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Home Page</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>

异常处理

我们可以使用@ControllerAdvice和@ExceptionHandler来全局处理异常。这里是一个简单的异常处理器示例:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ModelAndView resourceNotFound() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error");
        modelAndView.addObject("errorCode", "404");
        modelAndView.addObject("errorMessage", "Resource not found.");
        return modelAndView;
    }
}

Spring拦截器

Spring MVC拦截器(Interceptor)是Spring框架提供的一个功能,它允许我们在请求到达控制器之前和响应返回给客户端之前执行特定的逻辑。拦截器类似于Servlet中的过滤器(Filter),但它更专注于MVC模式中的请求处理流程。拦截器可以用于多种用途,如日志记录、权限检查、性能监控等。

拦截器的工作原理

拦截器在Spring MVC中是通过实现HandlerInterceptor接口或继承HandlerInterceptorAdapter类来定义的。当一个HTTP请求进入Spring MVC应用程序时,DispatcherServlet会根据配置的拦截器链(Interceptor Chain)依次调用每个拦截器的方法。拦截器可以决定是否继续处理请求,或者直接结束请求并返回响应。

HandlerInterceptor接口

HandlerInterceptor接口提供了三个主要方法:

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):该方法会在控制器方法调用之前执行。如果返回true,则继续处理;如果返回false,则中断后续处理。
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):该方法会在控制器方法调用之后,但在视图渲染之前执行。
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):该方法会在整个请求完成之后执行,可用于资源清理等工作。

自定义拦截器示例

下面是一个简单的自定义拦截器示例,演示了如何创建和配置拦截器。

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoggingInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("LoggingInterceptor.preHandle() is invoked");
        // 记录请求信息
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Request Method: " + request.getMethod());
        // 如果需要阻止请求继续,可以返回false
        return true; // 继续处理请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("LoggingInterceptor.postHandle() is invoked");
        // 在这里可以修改ModelAndView对象,比如添加额外的数据到模型中
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("LoggingInterceptor.afterCompletion() is invoked");
        // 清理工作或异常处理
    }
}

配置拦截器

要使拦截器生效,必须将其注册到Spring MVC配置中。如果是基于Java配置的方式,可以通过实现WebMvcConfigurer接口并重写addInterceptors方法来添加拦截器。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggingInterceptor())
                .addPathPatterns("/**") // 对所有路径生效
                .excludePathPatterns("/login", "/register"); // 排除某些路径
    }
}

使用注解简化拦截器

为了进一步简化配置,您可以使用@Component将拦截器标记为Spring Bean,并通过@Order指定拦截器的执行顺序。然后,只需确保它们被自动扫描即可。

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;

@Component
@Order(1)
public class AnotherLoggingInterceptor extends HandlerInterceptorAdapter {
    // 实现必要的拦截器方法...
}

在这种情况下,您不再需要显式地在WebMvcConfigurer中注册这个拦截器,因为它已经被Spring容器管理并且会自动加入到拦截器链中。

拦截器的应用场景

拦截器可以应用于多个方面,包括但不限于:

  • 认证与授权:在请求到达控制器之前验证用户身份或权限。
  • 日志记录:记录请求和响应的信息,便于调试和分析。
  • 性能监控:测量请求处理时间,监控应用性能。
  • 国际化支持:设置用户的语言偏好。
  • 数据预处理:在请求参数传递给控制器之前进行格式化或其他预处理操作。

Spring MVC拦截器提供了一种灵活的方式来扩展请求处理流程,而不需要修改现有的控制器代码。通过理解拦截器的工作机制及其配置方式,可以更加高效地构建出具备复杂业务逻辑的Web应用程序。欢迎大家一起讨论~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值