SpringMVC(SSM框架)

发布于:2024-04-29 ⋅ 阅读:(29) ⋅ 点赞:(0)

目录

一、MVC模式

二、获取请求参数

1. 通过HttpServletRequest获取

2. 通过方法参数获取

3. 通过PathVariable获取

4. 通过ModelAttributes获取

5. 使用@RequestBody获取请求体

三、处理响应

四、异常处理

1. 使用@ExceptionHandler注解

2. 使用@ControllerAdvice和@ResponseStatus注解

3. 使用Spring的SimpleMappingExceptionResolver

4. 使用@ResponseEntity

五、拦截器

六、Restful风格支持

七、JSON数据处理

八、跨域请求


一、MVC模式

SpringMVC 是一个基于 Java 的实现 MVC 设计模式的请求驱动类型的轻量级 Web 框架,它通过使用模型(Model)、视图(View)和控制器(Controller)将业务逻辑、数据、界面显示分离的方法组织代码,使程序结构更合理,更易于维护。

在 SpringMVC 中,MVC 模式的具体实现如下:

  1. 模型(Model):模型是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。在 SpringMVC 中,模型主要由 JavaBean 组成,这些 JavaBean 封装了从数据库中获取的数据,以供视图层显示。同时,模型还包含业务逻辑,如数据的验证和转换等。
  2. 视图(View):视图是应用程序中用户界面相关的部分,它依赖于模型。在 SpringMVC 中,视图通常是由 JSP、Thymeleaf 等模板引擎生成的 HTML 页面,它们负责将模型中的数据以用户友好的方式展现出来。
  3. 控制器(Controller):控制器是应用程序中处理用户输入的部分。在 SpringMVC 中,控制器负责接收用户的请求,然后调用相应的模型来处理请求,并选择合适的视图来显示处理后的结果。具体来说,控制器类通常是一个 Servlet,它使用 @Controller 注解进行标记,并处理由 DispatcherServlet 分发的请求。

SpringMVC 的工作流程大致如下:

  1. 用户发送请求到前端控制器(DispatcherServlet)。
  2. 前端控制器请求处理器映射器(HandlerMapping)查找 Handler(即控制器)。
  3. 处理器映射器找到 Handler 后返回给前端控制器,前端控制器调用处理器适配器(HandlerAdapter)去执行 Handler。
  4. 处理器适配器执行 Handler 后返回 ModelAndView(模型与视图)。
  5. 前端控制器请求视图解析器(ViewResolver)解析视图,然后返回真正的视图。
  6. 前端控制器对模型数据进行渲染,然后将视图发送给客户端。

这就是 SpringMVC 中 MVC 模式的具体实现和工作流程。通过将业务逻辑、数据和界面显示分离,MVC 模式使得代码更易于理解和维护,同时也提高了应用程序的可扩展性和可重用性。

二、获取请求参数

在SpringMVC中,有多种方法可以获取请求参数,包括从请求参数中直接获取、通过模型属性(ModelAttributes)获取以及使用注解方式获取。以下是一些常见的方法:

1. 通过HttpServletRequest获取

可以直接在控制器方法中注入HttpServletRequest对象,然后调用其方法来获取请求参数。

import javax.servlet.http.HttpServletRequest;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.GetMapping;  
  
@Controller  
public class MyController {  
  
    @GetMapping("/myMethod")  
    public String myMethod(HttpServletRequest request) {  
        String paramValue = request.getParameter("paramName");  
        // 处理paramValue...  
        return "viewName";  
    }  
}

2. 通过方法参数获取

SpringMVC支持直接将请求参数绑定到控制器方法的参数上。

import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RequestParam;  
  
@Controller  
public class MyController {  
  
    @GetMapping("/myMethod")  
    public String myMethod(@RequestParam String paramName) {  
        // 使用paramName...  
        return "viewName";  
    }  
}

使用@RequestParam注解时,如果请求中不存在该参数,默认情况下会抛出异常。如果参数是可选的,可以设置required属性为false

@GetMapping("/myMethod")  
public String myMethod(@RequestParam(required = false) String paramName) {  
    // ...  
}

3. 通过PathVariable获取

当URL路径中包含变量时,可以使用@PathVariable注解来获取这些值。

import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.PathVariable;  
  
@Controller  
public class MyController {  
  
    @GetMapping("/myMethod/{id}")  
    public String myMethod(@PathVariable("id") String id) {  
        // 使用id...  
        return "viewName";  
    }  
}

4. 通过ModelAttributes获取

使用@ModelAttribute注解,可以将请求参数绑定到模型对象上。

import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.ModelAttribute;  
  
@Controller  
public class MyController {  
  
    @ModelAttribute("myModel")  
    public MyModel createModel() {  
        return new MyModel();  
    }  
  
    @GetMapping("/myMethod")  
    public String myMethod(@ModelAttribute("myModel") MyModel model) {  
        // 使用model对象...  
        return "viewName";  
    }  
}

在上面的例子中,createModel方法会在每次请求处理之前被调用,创建一个新的MyModel对象。然后,SpringMVC会尝试将请求参数绑定到这个对象上,并在myMethod方法执行时将其作为参数传递。

5. 使用@RequestBody获取请求体

对于POST请求,如果请求体包含JSON或其他格式的数据,可以使用@RequestBody注解将请求体绑定到Java对象上。

import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.RequestBody;  
  
@Controller  
public class MyController {  
  
    @PostMapping("/myMethod")  
    public String myMethod(@RequestBody MyModel model) {  
        // 使用model对象...  
        return "viewName";  
    }  
}

在这个例子中,MyModel对象需要有一个合适的构造函数或setter方法,以便Spring能够将其从请求体中反序列化出来。

以上就是在SpringMVC中获取请求参数的几种常见方法。根据具体的需求和场景,你可以选择最适合你的方法来获取请求参数。

三、处理响应

在SpringMVC中,处理响应主要涉及控制器(Controller)返回数据给前端的过程。这个过程通常包括设置响应头、选择视图并渲染视图,以及将数据传递给视图进行展示。以下是SpringMVC处理响应的一些关键步骤和概念:

  1. 设置响应头
    • 在Controller的方法中,你可以使用HttpServletResponse对象来设置响应头。例如,你可以设置Content-Type来指定响应的MIME类型。
    • 你还可以使用@RequestMapping注解的produces属性来设置响应头的Content-Type
import javax.servlet.http.HttpServletResponse;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.RequestMapping;  
  
@Controller  
public class MyController {  
  
    @RequestMapping(value = "/example", produces = "application/json")  
    public String example(HttpServletResponse response) {  
        response.setHeader("Custom-Header", "CustomValue");  
        // 处理逻辑...  
        return "viewName";  
    }  
}
  1. 选择并渲染视图
    • SpringMVC使用视图解析器(ViewResolver)来确定应使用哪个视图来渲染响应。视图解析器根据逻辑视图名称(通常是控制器返回的字符串)解析为实际的视图资源(如JSP、Thymeleaf模板等)。
    • 你可以通过配置不同的视图解析器来支持不同的视图技术。
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.ViewResolver;  
import org.springframework.web.servlet.view.InternalResourceViewResolver;  
  
@Configuration  
public class WebConfig {  
  
    @Bean  
    public ViewResolver viewResolver() {  
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();  
        resolver.setPrefix("/WEB-INF/views/");  
        resolver.setSuffix(".jsp");  
        return resolver;  
    }  
}

在上面的配置中,InternalResourceViewResolver被配置为查找/WEB-INF/views/目录下的JSP文件,并添加.jsp后缀。

  1. 传递数据给视图
    • 控制器方法通常返回一个字符串(逻辑视图名称)和一个模型(Model),模型中包含要传递给视图的数据。你可以使用ModelModelMap对象来添加数据。
    • 视图可以使用这些数据来渲染响应。
import org.springframework.stereotype.Controller;  
import org.springframework.ui.Model;  
import org.springframework.web.bind.annotation.GetMapping;  
  
@Controller  
public class MyController {  
  
    @GetMapping("/showData")  
    public String showData(Model model) {  
        String message = "Hello, World!";  
        model.addAttribute("message", message);  
        return "viewName"; // 逻辑视图名称  
    }  
}

在上面的例子中,message被添加到模型中,并在viewName对应的视图中可用。

  1. 使用Server-Sent Events(SSE)处理流式响应
    • 对于需要实时推送数据到客户端的场景,你可以使用SpringMVC的Server-Sent Events功能。通过实现一个控制器并返回SseEmitter对象,你可以发送流式响应给客户端。
import org.springframework.http.ResponseEntity;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;  
  
@RestController  
public class EventController {  
  
    @GetMapping(value = "/event-stream", produces = "text/event-stream")  
    public ResponseEntity<SseEmitter> getEvents() {  
        SseEmitter emitter = new SseEmitter();  
        // 发送数据给客户端...  
        // emitter.send(SseEmitter.SseEventBuilder.event().data("Some data").build());  
        return ResponseEntity.ok().body(emitter);  
    }  
}

在这个例子中,getEvents方法返回一个SseEmitter对象,它允许你发送SSE事件给客户端。客户端可以通过监听这个流来实时接收服务器推送的事件。

综上所述,SpringMVC通过提供多种方式和工具来处理响应,使开发者能够灵活地控制如何返回数据给前端,并根据业务需求选择适当的视图技术进行渲染。

四、异常处理

在Spring MVC中,异常处理是一个非常重要的方面,因为它允许你优雅地处理应用程序中可能发生的错误情况,并向用户提供有意义的反馈。Spring MVC提供了几种不同的方式来处理异常。

1. 使用@ExceptionHandler注解

你可以使用@ExceptionHandler注解来创建一个处理特定类型异常的方法。这通常在你的控制器类或者一个专门的异常处理类中完成。

import org.springframework.web.bind.annotation.ControllerAdvice;  
import org.springframework.web.bind.annotation.ExceptionHandler;  
import org.springframework.http.HttpStatus;  
import org.springframework.http.ResponseEntity;  
import org.springframework.web.bind.annotation.ResponseBody;  
  
@ControllerAdvice  
public class GlobalExceptionHandler {  
  
    @ExceptionHandler(value = Exception.class)  
    @ResponseBody  
    public ResponseEntity<String> handleException(Exception e) {  
        // 处理异常,例如记录日志  
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);  
    }  
  
    @ExceptionHandler(value = CustomException.class)  
    @ResponseBody  
    public ResponseEntity<String> handleCustomException(CustomException e) {  
        // 处理自定义异常  
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);  
    }  
}

在上面的例子中,GlobalExceptionHandler类使用@ControllerAdvice注解来声明它作为一个全局异常处理器。然后,使用@ExceptionHandler注解来指定处理特定类型异常的方法。handleException方法处理所有Exception类型的异常,而handleCustomException方法处理CustomException类型的异常。

2. 使用@ControllerAdvice@ResponseStatus注解

除了@ExceptionHandler,你还可以使用@ControllerAdvice@ResponseStatus注解来定义全局的异常处理策略。

import org.springframework.web.bind.annotation.ControllerAdvice;  
import org.springframework.web.bind.annotation.ResponseStatus;  
import org.springframework.http.HttpStatus;  
import org.springframework.web.bind.annotation.ExceptionHandler;  
  
@ControllerAdvice  
public class GlobalExceptionHandler {  
  
    @ExceptionHandler(value = CustomException.class)  
    @ResponseStatus(HttpStatus.BAD_REQUEST)  
    public void handleCustomException(CustomException e) {  
        // 处理自定义异常,这里不需要返回任何东西  
        // 因为@ResponseStatus已经设置了响应状态码  
    }  
}

在这个例子中,当抛出CustomException异常时,Spring MVC会自动将HTTP响应状态码设置为BAD_REQUEST

3. 使用Spring的SimpleMappingExceptionResolver

如果你不想使用注解,你可以配置一个SimpleMappingExceptionResolver bean来映射异常到视图名称。

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.HandlerExceptionResolver;  
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;  
  
@Configuration  
public class WebConfig implements WebMvcConfigurer {  
  
    @Bean  
    public HandlerExceptionResolver handlerExceptionResolver() {  
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();  
        Properties mappings = new Properties();  
        mappings.setProperty("CustomException", "error/custom");  
        resolver.setExceptionMappings(mappings);  
        resolver.setDefaultErrorView("error/default");  
        resolver.setExceptionAttribute("ex");  
        return resolver;  
    }  
}

在这个配置中,SimpleMappingExceptionResolver被配置为将CustomException异常映射到名为error/custom的视图,而所有其他异常则映射到error/default视图。异常对象本身被添加到模型中,键名为ex

4. 使用@ResponseEntity

在控制器方法中,你也可以直接返回ResponseEntity对象来包含异常信息。这通常用于那些你希望直接控制HTTP响应的复杂场景。

import org.springframework.http.HttpStatus;  
import org.springframework.http.ResponseEntity;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  
  
@RestController  
public class MyController {  
  
    @GetMapping("/riskyOperation")  
    public ResponseEntity<String> riskyOperation() {  
        try {  
            // 执行一些可能抛出异常的操作  
        } catch (Exception e) {  
            // 处理异常并构建响应实体  
            return new

五、拦截器

SpringMVC中的拦截器(Interceptor)是一种动态拦截方法调用的机制,用于在请求到达Controller之前或之后对请求进行拦截和处理。拦截器在SpringMVC框架中扮演着重要的角色,它可以在整个请求处理的过程中对请求进行统一的处理,包括权限验证、日志记录、参数预处理等操作。

拦截器的主要作用包括:

  1. 权限验证:通过拦截器,可以对用户进行权限验证,判断用户是否有权限访问特定的资源。这通常涉及到校验token等安全凭证。
  2. 日志记录:拦截器可以记录请求操作日志,包括用户IP、访问时间等信息,以便统计请求访问量和分析用户行为。
  3. 预处理和后处理:拦截器可以对请求进行预处理和后处理。在请求到达Controller之前,拦截器可以执行一些必要的操作,如参数校验、数据转换等;在请求处理完成后,拦截器可以执行一些后续操作,如清理资源、更新状态等。
  4. 过滤请求:拦截器还可以对请求进行过滤,确保只有符合特定条件的请求才能被处理。这有助于防止非法请求和恶意攻击。

在SpringMVC中配置和使用拦截器通常包括以下步骤:

  1. 编写拦截器类:实现HandlerInterceptor接口,并重写其中的方法,如preHandle()(请求前处理)、postHandle()(请求后处理)和afterCompletion()(请求完成后处理)。
  2. 注册拦截器:在配置类中注册拦截器,实现WebMvcConfigurer接口,并重写相应的方法,将拦截器添加到拦截器链中。
  3. 配置拦截路径:指定拦截器需要拦截的路径和不需要拦截的路径。拦截器只会拦截访问控制器的方法,而不会拦截静态资源(如.jsp、html、css、image、js等)。

通过合理使用拦截器,可以提高SpringMVC应用程序的安全性、可维护性和性能。然而,也需要注意不要过度使用拦截器,以免增加不必要的复杂性和性能开销。

六、Restful风格支持

SpringMVC对RESTful风格提供了强大的支持,使开发者能够更轻松地创建符合RESTful原则的Web服务。RESTful风格的核心在于通过HTTP协议定义一组设计原则和约束条件,以实现对资源的统一访问和操作。

在SpringMVC中,实现RESTful风格的支持主要体现在以下几个方面:

  1. URL设计:RESTful风格要求使用简洁、易读的URL来表示资源。在SpringMVC中,你可以通过定义合适的控制器映射来实现这一点。例如,对于一个用户资源,你可以定义一个类似于/users/{id}的URL模式,其中{id}表示用户的唯一标识符。
  2. HTTP方法:RESTful风格强调使用HTTP方法(如GET、POST、PUT、DELETE等)来表示对资源的不同操作。SpringMVC支持这些HTTP方法,并允许你在控制器方法中指定它们。例如,你可以使用GET方法获取资源,使用POST方法创建资源,使用PUT方法更新资源,以及使用DELETE方法删除资源。
  3. 内容协商:RESTful风格支持内容协商,即根据客户端的请求头信息返回适当的内容类型。SpringMVC通过配置内容协商解析器和消息转换器来实现这一点。你可以配置多种内容类型(如JSON、XML等),并根据客户端的请求头自动选择返回的内容类型。
  4. 异常处理:在RESTful风格的Web服务中,异常处理是一个重要的方面。SpringMVC提供了灵活的异常处理机制,允许你自定义异常处理器来处理各种异常情况。你可以将异常信息封装为HTTP响应体,并返回给客户端。

此外,SpringMVC还提供了一些其他功能来增强对RESTful风格的支持,如使用@PathVariable注解来提取URL中的参数,使用@RequestBody@ResponseBody注解来处理请求体和响应体等。

总之,SpringMVC通过其灵活的控制器映射、HTTP方法支持、内容协商和异常处理机制等特性,为开发者提供了强大的RESTful风格支持,使他们能够轻松地构建符合RESTful原则的Web服务。

七、JSON数据处理

在SpringMVC中处理JSON数据,主要涉及到的是前端与后端的数据交互。以下是处理JSON数据的主要步骤和考虑因素:

  1. 添加依赖:首先,你需要在项目的pom.xml文件中添加Jackson的依赖。Jackson是一个Java库,可以将Java对象转换为JSON格式的字符串,也可以将JSON格式的字符串转换为Java对象。这样,你就可以在SpringMVC中轻松地使用JSON格式的数据了。

例如,添加以下依赖:

<dependency>  
    <groupId>com.fasterxml.jackson.core</groupId>  
    <artifactId>jackson-databind</artifactId>  
    <version>你的Jackson版本号</version>  
</dependency>
  1. 配置SpringMVC:确保你的SpringMVC配置已经正确设置,包括前端控制器(DispatcherServlet)和相关的配置文件。这些配置将确保SpringMVC能够正确地处理请求和响应。
  2. 使用@ResponseBody注解:在你的Controller方法中,使用@ResponseBody注解来指示该方法返回的数据应该直接写入HTTP响应体中,而不是解析为视图名称。这样,你就可以直接返回JSON格式的数据给前端了。

例如:

@RequestMapping(value = "/getUser", method = RequestMethod.GET)  
@ResponseBody  
public User getUser() {  
    User user = new User();  
    user.setName("张三");  
    user.setAge(20);  
    return user;  
}

在上述示例中,当用户访问/getUser路径时,SpringMVC会调用getUser()方法,并将返回的User对象转换为JSON格式的字符串,然后写入HTTP响应体中。
4. 处理前端请求:在前端,你可以使用AJAX或其他方式发送请求到后端,并处理返回的JSON数据。通常,你可以使用JavaScript的fetch API或jQuery的$.ajax方法来发送请求,并使用JSON.parse()方法来将返回的JSON字符串转换为JavaScript对象。
5. 异常处理:当处理JSON数据时,可能会出现各种异常,如数据格式错误、数据转换失败等。因此,你需要确保你的代码能够优雅地处理这些异常,并返回合适的错误信息给前端。你可以使用SpringMVC的全局异常处理机制来实现这一点。
6. 测试:最后,不要忘记对你的JSON数据处理代码进行测试,确保它能够正确地处理各种情况,并返回预期的结果。你可以使用单元测试、集成测试或端到端测试来验证你的代码。

通过遵循上述步骤和考虑因素,你应该能够在SpringMVC中有效地处理JSON数据,并实现前后端之间的顺畅交互。

八、跨域请求

在SpringMVC中处理跨域请求(Cross-Origin Resource Sharing, CORS)是一个常见的需求,特别是在构建前后端分离的Web应用时。跨域请求指的是浏览器从一个源(域、协议和端口)的页面发起请求到另一个源的资源。出于安全考虑,浏览器默认会限制这种跨域请求。然而,通过一些配置,SpringMVC可以允许这种跨域请求。

在SpringMVC中处理跨域请求的主要方法有以下几种:

  1. 全局CORS配置:你可以创建一个配置类,并重写WebMvcConfigurer接口的addCorsMappings方法,来全局配置CORS。这个方法允许你指定哪些路径和哪些域可以访问你的资源。

示例代码如下:

@Configuration  
public class MyConfiguration {  
  
    @Bean  
    public WebMvcConfigurer corsConfigurer() {  
        return new WebMvcConfigurer() {  
            @Override  
            public void addCorsMappings(CorsRegistry registry) {  
                // 添加映射路径  
                registry.addMapping("/**")  
                        .allowedOrigins("*") // 允许所有域访问  
                        .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许的请求方法  
                        .maxAge(168000) // 预检间隔时间  
                        .allowedHeaders("*"); // 允许头部设置  
            }  
        };  
    }  
}

在这个例子中,addMapping("/**")表示所有路径都允许跨域请求,allowedOrigins("*")表示允许所有来源的域名进行访问。你可以根据你的实际需求调整这些设置。

  1. 使用注解:对于特定的控制器或方法,你也可以使用@CrossOrigin注解来允许跨域请求。这个注解可以添加到类或方法上,以控制特定资源的跨域访问。

例如:

@RestController  
@CrossOrigin(origins = "http://example.com")  
public class MyController {  
    // ...  
}

或者:

@RestController  
public class MyController {  
  
    @GetMapping("/myEndpoint")  
    @CrossOrigin(origins = "http://example.com")  
    public ResponseEntity<String> myEndpoint() {  
        // ...  
    }  
}
  1. 过滤器:在SpringMVC 4.x及以下版本中,你可能需要配置一个过滤器来处理跨域请求。这涉及到编写自定义的过滤器类,并在Spring配置中注册它。然而,随着Spring版本的更新,使用全局CORS配置或注解通常更为简单和方便。

请注意,处理跨域请求时,你需要仔细考虑安全性问题。允许所有来源的域名进行访问可能会带来安全风险。因此,你应该根据实际需求来限制允许的域名和请求方法。同时,你也应该确保你的应用已经采取了其他必要的安全措施,如使用HTTPS、验证和授权等。


文章制作不易,如果有帮助的话,还希望能给个点赞关注支持一下,谢谢大家!🙏🙏🙏