赞
踩
MVC(Model-View-Controller)模式是一种设计模式,用于分离应用程序的不同方面,以提高代码的组织性和可维护性。在Spring MVC框架中,MVC模式的作用是将应用程序的不同职责分开,从而简化开发和维护过程。MVC模式的三个主要组件是:
Model(模型):表示应用程序的数据和业务逻辑。模型通常包括与数据库交互的部分以及用于处理业务逻辑的类。在Spring MVC中,模型通常由POJO(Plain Old Java Object)类表示,这些类包含数据和业务逻辑。
View(视图):负责呈现数据给用户。视图将模型的数据以用户友好的格式显示出来。在Spring MVC中,视图通常是JSP、Thymeleaf、FreeMarker等模板文件,这些文件负责渲染HTML页面。
Controller(控制器):处理用户的输入并更新模型和视图。控制器接收用户请求,调用相应的业务逻辑,并决定使用哪个视图来显示结果。在Spring MVC中,控制器是一个标注了@Controller
注解的类,负责处理请求并返回一个视图名称或数据。
在Spring MVC框架中,处理请求的流程通常如下:
用户发起请求:用户通过浏览器发送一个HTTP请求。
前端控制器:Spring MVC的DispatcherServlet
作为前端控制器接收请求,并根据请求的URL将其分发到合适的控制器。
控制器处理请求:控制器处理请求,调用模型中的业务逻辑,并将数据准备好。
选择视图:控制器选择一个视图,并将模型数据传递给视图。
渲染视图:视图将模型数据呈现给用户。
返回响应:前端控制器将视图的渲染结果返回给用户。
通过这种分层结构,MVC模式使得代码更易于理解和维护,因为它将数据处理、业务逻辑和用户界面分开处理。
对于SpringMVC的使用其实很简单,可以看我下面这篇文章:
下面是SpringMVC常用的注解:
@Controller
:
@Controller
public class MyController {
// ...
}
@RestController
:
@Controller
和 @ResponseBody
,用于构建 RESTful Web 服务。控制器方法返回的数据会被自动序列化为 JSON 或 XML 格式。@RestController
public class MyRestController {
// ...
}
@RequestMapping
:
@RequestMapping("/hello")
public String sayHello() {
return "helloView";
}
@GetMapping
:
@RequestMapping(method = RequestMethod.GET)
的快捷方式。@GetMapping("/users")
public List<User> getUsers() {
// ...
}
@PostMapping
:
@RequestMapping(method = RequestMethod.POST)
的快捷方式。@PostMapping("/users")
public User createUser(@RequestBody User user) {
// ...
}
@PutMapping
:
@RequestMapping(method = RequestMethod.PUT)
的快捷方式。@PutMapping("/users/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
// ...
}
@DeleteMapping
:
@RequestMapping(method = RequestMethod.DELETE)
的快捷方式。@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable Long id) {
// ...
}
@PathVariable
:
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
// ...
}
@RequestParam
:
@GetMapping("/search")
public List<User> searchUsers(@RequestParam String query) {
// ...
}
@RequestBody
:
@PostMapping("/users")
public User createUser(@RequestBody User user) {
// ...
}
@RequestHeader
:
@GetMapping("/headers")
public String getHeaders(@RequestHeader("User-Agent") String userAgent) {
// ...
}
@RequestAttribute
:
@GetMapping("/attributes")
public String getAttributes(@RequestAttribute("attributeName") String attributeValue) {
// ...
}
@ModelAttribute
:
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("attributeName", "attributeValue");
}
@SessionAttributes
:
@Controller
@SessionAttributes("user")
public class SessionController {
// ...
}
@ControllerAdvice
:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<String> handleException(Exception ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@ExceptionHandler
:
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseBody
public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
旧版返回jsp的流程
旧版流程总结
DispatcherServlet
控制器handle
HandleMapping
根据先前存储的映射规则,返回一个处理器执行链DispatcherServlet
将执行handle
的命令发送到HandleAdapter
处理适配器HandleAdapter
将请求体中的参数映射到处理函数中,然后接收响应数据,并对相应数据做处理然后返回一个ModelAndView
对象给前端控制器前后端分离开发处理请求流程
前后端分离开发流程
handle
HandlerAdaptor
执行,HandlerAdaptor
负责处理传入参数和返回值HttpMessageConverter
将返回结果转换为json后直接响应SpringMVC 的异常处理器用于集中处理应用程序中的异常,以便为用户提供一致的错误响应,同时使代码更加干净和可维护。
@ExceptionHandler
:在控制器中使用,专门处理某个控制器方法抛出的特定异常。@ControllerAdvice
:用于定义全局异常处理逻辑,可以处理应用程序中的所有控制器的异常。@ResponseStatus
:用于定义异常类的 HTTP 状态码,简化异常响应的处理。以下是一个简短的示例,展示了如何使用 @ControllerAdvice
和 @ExceptionHandler
实现一个全局异常处理类:
1. 创建自定义异常类
首先,定义一个自定义异常类:
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
2. 创建异常处理类
使用 @ControllerAdvice
和 @ExceptionHandler
注解创建一个全局异常处理类:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) @ResponseBody public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) { // 处理资源未找到异常,返回 404 状态码和异常消息 return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND); } @ExceptionHandler(Exception.class) @ResponseBody public ResponseEntity<String> handleGenericException(Exception ex) { // 处理其他异常,返回 500 状态码和异常消息 return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } }
ResourceNotFoundException
时,handleResourceNotFoundException
方法会处理此异常,并返回一个 404 状态码。handleGenericException
方法会处理,并返回一个 500 状态码。SpringMVC 的拦截器是用于在请求处理过程中对请求和响应进行预处理和后处理的组件。它们允许开发者在请求到达控制器之前、控制器处理请求之后,以及视图渲染之前执行一些额外的操作,如日志记录、安全检查、性能监控等。
SpringMVC 提供了一个 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)
:
1. 创建拦截器类
实现 HandlerInterceptor
接口,并重写其方法:
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理之前执行 System.out.println("Before handling the request"); return true; // 返回 true 继续处理请求,返回 false 中止请求处理 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在请求处理后,视图渲染之前执行 System.out.println("After handling the request but before rendering the view"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在视图渲染完成后执行 System.out.println("After completing the request"); if (ex != null) { ex.printStackTrace(); } } }
2. 注册拦截器
在 SpringMVC 的配置类中注册拦截器:
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 MyInterceptor())
.addPathPatterns("/**"); // 设置拦截路径
}
}
SpringMVC 的过滤器(Filter)是一种用于在请求和响应处理过程中对请求数据和响应数据进行预处理和后处理的机制。它们可以用于实现各种功能,如日志记录、安全检查、请求修改等。过滤器是在 Servlet 容器中运行的,而不是 Spring 容器中。
javax.servlet.Filter
接口用于定义过滤器。它包含以下方法:
void init(FilterConfig filterConfig)
:
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
:
FilterChain
的 doFilter
方法继续处理链中的下一个过滤器或目标资源。void destroy()
:
1. 创建过滤器类
实现 Filter
接口,并重写其方法:
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/*") // 通过注解配置过滤器的拦截路径 public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化过滤器 System.out.println("Filter initialized"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 处理请求之前 System.out.println("Before request processing"); // 继续处理请求,调用链中的下一个过滤器或目标资源 chain.doFilter(request, response); // 处理响应之后 System.out.println("After request processing"); } @Override public void destroy() { // 关闭过滤器 System.out.println("Filter destroyed"); } }
2. 注册过滤器
在 Spring Boot 中,你也可以通过 Java 配置类注册过滤器:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter> loggingFilter() {
FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MyFilter());
registrationBean.addUrlPatterns("/*"); // 设置过滤器的拦截路径
return registrationBean;
}
}
在 SpringMVC 中,跨域问题(Cross-Origin Resource Sharing, CORS)通常是指不同源的客户端请求访问服务器资源时遇到的限制。为了解决这个问题,可以配置允许跨域访问的策略。SpringMVC 提供了多种方式来处理跨域请求。
全局 CORS 配置:
在 Spring Boot 应用中,可以通过配置全局 CORS 规则来允许特定的来源进行跨域访问。这种方式可以在全局范围内对所有控制器应用 CORS 配置。
示例:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://example.com") // 允许的源 .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的 HTTP 方法 .allowedHeaders("*") // 允许的请求头 .allowCredentials(true); // 是否允许凭证(如 cookies) } }
在 Controller 层使用 @CrossOrigin
注解:
可以在单个控制器或具体的控制器方法上使用 @CrossOrigin
注解来指定允许的跨域配置。这种方式适用于需要对某些特定控制器或方法进行跨域配置的情况。
示例:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyController {
@CrossOrigin(origins = "http://example.com")
@GetMapping("/data")
public String getData() {
return "Some data";
}
}
在 Spring Security 中配置 CORS:
如果应用程序使用了 Spring Security,必须在 Security 配置中显式启用 CORS 配置。Spring Security 默认情况下不会允许 CORS 请求,因此需要进行额外的配置。
示例:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .cors() // 启用 CORS .and() .csrf().disable() // 根据需要配置 CSRF .authorizeRequests() .anyRequest().authenticated(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://example.com")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。