1. Spring MVC 简介
Spring MVC(Model-View-Controller)是Spring Framework的一个模块,用于构建基于Web的应用程序。它通过将应用程序的不同方面(输入逻辑、业务逻辑和UI逻辑)分离来促进开发和维护。
2. Spring MVC 核心概念
DispatcherServlet
DispatcherServlet是Spring MVC的核心组件,负责接收HTTP请求,将其转发给适当的处理器,并将处理结果返回给客户端。它的作用包括:
分发请求到相应的处理器(Controller)。
处理器调用后将数据返回给视图(View)。
将视图渲染成最终的HTTP响应。
Controller
Controller用于处理用户请求并返回模型和视图。控制器是通过注解@Controller标记的类。
ModelAndView
ModelAndView是一个封装了模型数据和视图名称的对象。控制器通过返回ModelAndView对象将数据传递给视图。
ViewResolver
ViewResolver负责将逻辑视图名称解析为具体的视图实现,例如JSP、Thymeleaf等。
3. Spring MVC 配置
XML 配置
<!-- web.xml -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- dispatcher-servlet.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.example.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Java 配置(基于注解)
// WebConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller")
public class WebConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
// WebAppInitializer.java
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher",
new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
4. Spring MVC 基本示例
控制器示例
@Controller
public class HomeController {
@RequestMapping("/")
public String home(Model model) {
model.addAttribute("message", "Welcome to Spring MVC!");
return "home"; // 逻辑视图名,实际视图为 /WEB-INF/views/home.jsp
}
}
表单处理
@Controller
public class UserController {
@GetMapping("/user")
public String showForm(Model model) {
model.addAttribute("user", new User());
return "userForm";
}
@PostMapping("/user")
public String submitForm(@ModelAttribute User user, Model model) {
model.addAttribute("user", user);
return "userDetail";
}
}
数据校验
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
public class User {
@NotEmpty
private String name;
@Size(min = 6, max = 15)
private String password;
// getters and setters
}
// 控制器
@Controller
public class UserController {
@GetMapping("/user")
public String showForm(Model model) {
model.addAttribute("user", new User());
return "userForm";
}
@PostMapping("/user")
public String submitForm(@Valid @ModelAttribute User user, BindingResult result, Model model) {
if (result.hasErrors()) {
return "userForm";
}
model.addAttribute("user", user);
return "userDetail";
}
}
5. 高级主题
拦截器
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Request URL: " + request.getRequestURL());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 执行处理器之后
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 完成请求处理
}
}
// 配置拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor());
}
}
异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex) {
ModelAndView mav = new ModelAndView("error");
mav.addObject("message", ex.getMessage());
return mav;
}
}
文件上传
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10485760); // 10MB
return resolver;
}
}
// 控制器
@Controller
public class FileUploadController {
@GetMapping("/upload")
public String uploadForm() {
return "uploadForm";
}
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file, Model model) {
if (!file.isEmpty()) {
// 处理文件
model.addAttribute("message", "File uploaded successfully: " + file.getOriginalFilename());
} else {
model.addAttribute("message", "File upload failed because the file was empty.");
}
return "uploadStatus";
}
}