目录
[1. 通过HttpServletRequest获取](#1. 通过HttpServletRequest获取)
[2. 通过方法参数获取](#2. 通过方法参数获取)
[3. 通过PathVariable获取](#3. 通过PathVariable获取)
[4. 通过ModelAttributes获取](#4. 通过ModelAttributes获取)
[5. 使用@RequestBody获取请求体](#5. 使用@RequestBody获取请求体)
[1. 使用@ExceptionHandler注解](#1. 使用@ExceptionHandler注解)
[2. 使用@ControllerAdvice和@ResponseStatus注解](#2. 使用@ControllerAdvice和@ResponseStatus注解)
[3. 使用Spring的SimpleMappingExceptionResolver](#3. 使用Spring的SimpleMappingExceptionResolver)
[4. 使用@ResponseEntity](#4. 使用@ResponseEntity)
一、MVC模式
SpringMVC 是一个基于 Java 的实现 MVC 设计模式的请求驱动类型的轻量级 Web 框架,它通过使用模型(Model)、视图(View)和控制器(Controller)将业务逻辑、数据、界面显示分离的方法组织代码,使程序结构更合理,更易于维护。
在 SpringMVC 中,MVC 模式的具体实现如下:
- 模型(Model):模型是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。在 SpringMVC 中,模型主要由 JavaBean 组成,这些 JavaBean 封装了从数据库中获取的数据,以供视图层显示。同时,模型还包含业务逻辑,如数据的验证和转换等。
- 视图(View):视图是应用程序中用户界面相关的部分,它依赖于模型。在 SpringMVC 中,视图通常是由 JSP、Thymeleaf 等模板引擎生成的 HTML 页面,它们负责将模型中的数据以用户友好的方式展现出来。
- 控制器(Controller):控制器是应用程序中处理用户输入的部分。在 SpringMVC 中,控制器负责接收用户的请求,然后调用相应的模型来处理请求,并选择合适的视图来显示处理后的结果。具体来说,控制器类通常是一个 Servlet,它使用 @Controller 注解进行标记,并处理由 DispatcherServlet 分发的请求。
SpringMVC 的工作流程大致如下:
- 用户发送请求到前端控制器(DispatcherServlet)。
- 前端控制器请求处理器映射器(HandlerMapping)查找 Handler(即控制器)。
- 处理器映射器找到 Handler 后返回给前端控制器,前端控制器调用处理器适配器(HandlerAdapter)去执行 Handler。
- 处理器适配器执行 Handler 后返回 ModelAndView(模型与视图)。
- 前端控制器请求视图解析器(ViewResolver)解析视图,然后返回真正的视图。
- 前端控制器对模型数据进行渲染,然后将视图发送给客户端。
这就是 SpringMVC 中 MVC 模式的具体实现和工作流程。通过将业务逻辑、数据和界面显示分离,MVC 模式使得代码更易于理解和维护,同时也提高了应用程序的可扩展性和可重用性。
二、获取请求参数
在SpringMVC中,有多种方法可以获取请求参数,包括从请求参数中直接获取、通过模型属性(ModelAttributes)获取以及使用注解方式获取。以下是一些常见的方法:
1. 通过HttpServletRequest获取
可以直接在控制器方法中注入HttpServletRequest
对象,然后调用其方法来获取请求参数。
java
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支持直接将请求参数绑定到控制器方法的参数上。
java
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
。
java
@GetMapping("/myMethod")
public String myMethod(@RequestParam(required = false) String paramName) {
// ...
}
3. 通过PathVariable获取
当URL路径中包含变量时,可以使用@PathVariable
注解来获取这些值。
java
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
注解,可以将请求参数绑定到模型对象上。
java
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对象上。
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处理响应的一些关键步骤和概念:
- 设置响应头 :
- 在Controller的方法中,你可以使用
HttpServletResponse
对象来设置响应头。例如,你可以设置Content-Type
来指定响应的MIME类型。 - 你还可以使用
@RequestMapping
注解的produces
属性来设置响应头的Content-Type
。
- 在Controller的方法中,你可以使用
java
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";
}
}
- 选择并渲染视图 :
- SpringMVC使用视图解析器(ViewResolver)来确定应使用哪个视图来渲染响应。视图解析器根据逻辑视图名称(通常是控制器返回的字符串)解析为实际的视图资源(如JSP、Thymeleaf模板等)。
- 你可以通过配置不同的视图解析器来支持不同的视图技术。
java
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
后缀。
- 传递数据给视图 :
- 控制器方法通常返回一个字符串(逻辑视图名称)和一个模型(Model),模型中包含要传递给视图的数据。你可以使用
Model
或ModelMap
对象来添加数据。 - 视图可以使用这些数据来渲染响应。
- 控制器方法通常返回一个字符串(逻辑视图名称)和一个模型(Model),模型中包含要传递给视图的数据。你可以使用
java
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
对应的视图中可用。
- 使用Server-Sent Events(SSE)处理流式响应 :
- 对于需要实时推送数据到客户端的场景,你可以使用SpringMVC的Server-Sent Events功能。通过实现一个控制器并返回
SseEmitter
对象,你可以发送流式响应给客户端。
- 对于需要实时推送数据到客户端的场景,你可以使用SpringMVC的Server-Sent Events功能。通过实现一个控制器并返回
java
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
注解来创建一个处理特定类型异常的方法。这通常在你的控制器类或者一个专门的异常处理类中完成。
java
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
注解来定义全局的异常处理策略。
java
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来映射异常到视图名称。
java
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响应的复杂场景。
java
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框架中扮演着重要的角色,它可以在整个请求处理的过程中对请求进行统一的处理,包括权限验证、日志记录、参数预处理等操作。
拦截器的主要作用包括:
- 权限验证:通过拦截器,可以对用户进行权限验证,判断用户是否有权限访问特定的资源。这通常涉及到校验token等安全凭证。
- 日志记录:拦截器可以记录请求操作日志,包括用户IP、访问时间等信息,以便统计请求访问量和分析用户行为。
- 预处理和后处理:拦截器可以对请求进行预处理和后处理。在请求到达Controller之前,拦截器可以执行一些必要的操作,如参数校验、数据转换等;在请求处理完成后,拦截器可以执行一些后续操作,如清理资源、更新状态等。
- 过滤请求:拦截器还可以对请求进行过滤,确保只有符合特定条件的请求才能被处理。这有助于防止非法请求和恶意攻击。
在SpringMVC中配置和使用拦截器通常包括以下步骤:
- 编写拦截器类 :实现
HandlerInterceptor
接口,并重写其中的方法,如preHandle()
(请求前处理)、postHandle()
(请求后处理)和afterCompletion()
(请求完成后处理)。 - 注册拦截器 :在配置类中注册拦截器,实现
WebMvcConfigurer
接口,并重写相应的方法,将拦截器添加到拦截器链中。 - 配置拦截路径:指定拦截器需要拦截的路径和不需要拦截的路径。拦截器只会拦截访问控制器的方法,而不会拦截静态资源(如.jsp、html、css、image、js等)。
通过合理使用拦截器,可以提高SpringMVC应用程序的安全性、可维护性和性能。然而,也需要注意不要过度使用拦截器,以免增加不必要的复杂性和性能开销。
六、Restful风格支持
SpringMVC对RESTful风格提供了强大的支持,使开发者能够更轻松地创建符合RESTful原则的Web服务。RESTful风格的核心在于通过HTTP协议定义一组设计原则和约束条件,以实现对资源的统一访问和操作。
在SpringMVC中,实现RESTful风格的支持主要体现在以下几个方面:
- URL设计 :RESTful风格要求使用简洁、易读的URL来表示资源。在SpringMVC中,你可以通过定义合适的控制器映射来实现这一点。例如,对于一个用户资源,你可以定义一个类似于
/users/{id}
的URL模式,其中{id}
表示用户的唯一标识符。 - HTTP方法:RESTful风格强调使用HTTP方法(如GET、POST、PUT、DELETE等)来表示对资源的不同操作。SpringMVC支持这些HTTP方法,并允许你在控制器方法中指定它们。例如,你可以使用GET方法获取资源,使用POST方法创建资源,使用PUT方法更新资源,以及使用DELETE方法删除资源。
- 内容协商:RESTful风格支持内容协商,即根据客户端的请求头信息返回适当的内容类型。SpringMVC通过配置内容协商解析器和消息转换器来实现这一点。你可以配置多种内容类型(如JSON、XML等),并根据客户端的请求头自动选择返回的内容类型。
- 异常处理:在RESTful风格的Web服务中,异常处理是一个重要的方面。SpringMVC提供了灵活的异常处理机制,允许你自定义异常处理器来处理各种异常情况。你可以将异常信息封装为HTTP响应体,并返回给客户端。
此外,SpringMVC还提供了一些其他功能来增强对RESTful风格的支持,如使用@PathVariable
注解来提取URL中的参数,使用@RequestBody
和@ResponseBody
注解来处理请求体和响应体等。
总之,SpringMVC通过其灵活的控制器映射、HTTP方法支持、内容协商和异常处理机制等特性,为开发者提供了强大的RESTful风格支持,使他们能够轻松地构建符合RESTful原则的Web服务。
七、JSON数据处理
在SpringMVC中处理JSON数据,主要涉及到的是前端与后端的数据交互。以下是处理JSON数据的主要步骤和考虑因素:
- 添加依赖 :首先,你需要在项目的
pom.xml
文件中添加Jackson的依赖。Jackson是一个Java库,可以将Java对象转换为JSON格式的字符串,也可以将JSON格式的字符串转换为Java对象。这样,你就可以在SpringMVC中轻松地使用JSON格式的数据了。
例如,添加以下依赖:
XML
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>你的Jackson版本号</version>
</dependency>
- 配置SpringMVC:确保你的SpringMVC配置已经正确设置,包括前端控制器(DispatcherServlet)和相关的配置文件。这些配置将确保SpringMVC能够正确地处理请求和响应。
- 使用@ResponseBody注解 :在你的Controller方法中,使用
@ResponseBody
注解来指示该方法返回的数据应该直接写入HTTP响应体中,而不是解析为视图名称。这样,你就可以直接返回JSON格式的数据给前端了。
例如:
java
@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响应体中。
-
处理前端请求 :在前端,你可以使用AJAX或其他方式发送请求到后端,并处理返回的JSON数据。通常,你可以使用JavaScript的
fetch
API或jQuery的$.ajax
方法来发送请求,并使用JSON.parse()
方法来将返回的JSON字符串转换为JavaScript对象。 -
异常处理 :当处理JSON数据时,可能会出现各种异常,如数据格式错误、数据转换失败等。因此,你需要确保你的代码能够优雅地处理这些异常,并返回合适的错误信息给前端。你可以使用SpringMVC的全局异常处理机制来实现这一点。
-
测试:最后,不要忘记对你的JSON数据处理代码进行测试,确保它能够正确地处理各种情况,并返回预期的结果。你可以使用单元测试、集成测试或端到端测试来验证你的代码。
通过遵循上述步骤和考虑因素,你应该能够在SpringMVC中有效地处理JSON数据,并实现前后端之间的顺畅交互。
八、跨域请求
在SpringMVC中处理跨域请求(Cross-Origin Resource Sharing, CORS)是一个常见的需求,特别是在构建前后端分离的Web应用时。跨域请求指的是浏览器从一个源(域、协议和端口)的页面发起请求到另一个源的资源。出于安全考虑,浏览器默认会限制这种跨域请求。然而,通过一些配置,SpringMVC可以允许这种跨域请求。
在SpringMVC中处理跨域请求的主要方法有以下几种:
- 全局CORS配置 :你可以创建一个配置类,并重写
WebMvcConfigurer
接口的addCorsMappings
方法,来全局配置CORS。这个方法允许你指定哪些路径和哪些域可以访问你的资源。
示例代码如下:
java
@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("*")
表示允许所有来源的域名进行访问。你可以根据你的实际需求调整这些设置。
- 使用注解 :对于特定的控制器或方法,你也可以使用
@CrossOrigin
注解来允许跨域请求。这个注解可以添加到类或方法上,以控制特定资源的跨域访问。
例如:
java
@RestController
@CrossOrigin(origins = "http://example.com")
public class MyController {
// ...
}
或者:
java
@RestController
public class MyController {
@GetMapping("/myEndpoint")
@CrossOrigin(origins = "http://example.com")
public ResponseEntity<String> myEndpoint() {
// ...
}
}
- 过滤器:在SpringMVC 4.x及以下版本中,你可能需要配置一个过滤器来处理跨域请求。这涉及到编写自定义的过滤器类,并在Spring配置中注册它。然而,随着Spring版本的更新,使用全局CORS配置或注解通常更为简单和方便。
请注意,处理跨域请求时,你需要仔细考虑安全性问题。允许所有来源的域名进行访问可能会带来安全风险。因此,你应该根据实际需求来限制允许的域名和请求方法。同时,你也应该确保你的应用已经采取了其他必要的安全措施,如使用HTTPS、验证和授权等。
文章制作不易,如果有帮助的话,还希望能给个点赞 和关注支持一下,谢谢大家! 🙏🙏🙏