home
)解析为物理视图(如/WEB-INF/home.jsp
)。DispatcherServlet
、视图解析器、组件扫描。@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
@PostMapping("/register")
public String submitForm(@ModelAttribute User user) {
// 处理用户注册
return "result";
}
MultipartResolver
:<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
// 保存文件
}
return "redirect:/success";
}
HandlerInterceptor
接口:public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 检查用户登录状态
return true; // 放行请求
}
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/admin/**");
}
@ControllerAdvice
:@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex) {
ModelAndView mav = new ModelAndView("error");
mav.addObject("message", ex.getMessage());
return mav;
}
}
WebApplicationContext
,初始化HandlerMapping、ViewResolver等。doDispatch()
方法源码分析。HandlerMethodArgumentResolver
。ViewResolver
接口。DeferredResult
或Callable
处理耗时操作:@GetMapping("/async")
public DeferredResult<String> asyncTask() {
DeferredResult<String> result = new DeferredResult<>();
CompletableFuture.runAsync(() -> {
// 模拟耗时操作
result.setResult("Async Result");
});
return result;
}
@RestController
和@ResponseBody
。@EnableWebSocket
配置实时通信。Controller示例:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/list")
public String listUsers(Model model) {
model.addAttribute("users", userService.findAll());
return "user/list";
}
}
Thymeleaf视图:
<table>
<tr th:each="user : ${users}">
<td th:text="${user.username}">td>
<td th:text="${user.email}">td>
tr>
table>
基础阶段
进阶阶段
实战阶段
高级阶段
DispatcherServlet
→ FrameworkServlet
→ HttpServletBean
→ HttpServlet
。initWebApplicationContext()
方法创建或继承父容器的上下文。HandlerMapping
、HandlerAdapter
、ViewResolver
等,通过initStrategies()
方法加载。RequestMappingHandlerMapping
)。doDispatch()
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 获取HandlerExecutionChain(包含Controller方法及拦截器)
HandlerExecutionChain mappedHandler = getHandler(request);
// 2. 获取HandlerAdapter(如RequestMappingHandlerAdapter)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 执行拦截器的preHandle()
if (!mappedHandler.applyPreHandle(request, response)) return;
// 4. 调用Controller方法,返回ModelAndView
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
// 5. 处理视图渲染,触发拦截器的postHandle()
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(request, response, mv);
// 6. 渲染视图并触发afterCompletion()
processDispatchResult(request, response, mappedHandler, mv, null);
}
RequestMappingHandlerMapping
通过getHandlerInternal()
方法匹配URL和@RequestMapping
注解。HandlerMethodArgumentResolver
和HandlerMethodReturnValueHandler
的扩展机制。@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable(); // 启用默认Servlet(Tomcat的DefaultServlet)
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
CacheControl
配置静态资源缓存策略。registry.addResourceHandler("/images/**")
.addResourceLocations("classpath:/images/")
.setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS));
@Bean
public AsyncTaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
return executor;
}
@GetMapping("/async")
public DeferredResult<String> asyncWithTimeout() {
DeferredResult<String> result = new DeferredResult<>(5000L); // 5秒超时
result.onTimeout(() -> result.setErrorResult("Request Timeout"));
return result;
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and().formLogin();
}
}
public class JwtUtils {
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.signWith(SignatureAlgorithm.HS512, "secretKey")
.compact();
}
}
public class JwtFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
String token = request.getHeader("Authorization");
if (validateToken(token)) {
// 解析Token并设置SecurityContext
}
chain.doFilter(request, response);
}
}
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetUser() throws Exception {
mockMvc.perform(get("/user/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("admin"));
}
}
@SpringBootTest
@Transactional
@Rollback
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testCreateUser() {
User user = new User("test", "[email protected]");
userService.save(user);
assertNotNull(userService.findByEmail("[email protected]"));
}
}
# application.properties
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@GetMapping
public List<User> listUsers() {
return userService.findAll();
}
}
public class ApiResponse<T> {
private int code;
private String message;
private T data;
// 构造方法、Getter/Setter
}
ApplicationContext
、BeanFactory
)。DispatcherServlet
的doDispatch()
方法入手。