Spring Boot 为 Web 开发提供了强大的支持,包括 REST API、模板引擎、静态资源处理等功能。
Spring MVC 集成
- 自动配置 Spring MVC 组件
- 内置 Tomcat、Jetty 或 Undertow 服务器
- 静态资源自动映射
- 错误页面自动配置
控制器注解
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
// GET 请求 - 获取所有用户
@GetMapping("/users")
public List getUsers() {
return userService.findAll();
}
// GET 请求 - 根据ID获取用户
@GetMapping("/users/{id}")
public ResponseEntity getUserById(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
// POST 请求 - 创建用户
@PostMapping("/users")
public ResponseEntity createUser(@RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
// PUT 请求 - 更新用户
@PutMapping("/users/{id}")
public ResponseEntity updateUser(@PathVariable Long id,
@RequestBody User user) {
user.setId(id);
User updatedUser = userService.update(user);
return ResponseEntity.ok(updatedUser);
}
// DELETE 请求 - 删除用户
@DeleteMapping("/users/{id}")
public ResponseEntity deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
请求参数处理
@RestController
public class RequestController {
// @PathVariable - 路径变量
@GetMapping("/users/{id}/orders/{orderId}")
public String getOrder(@PathVariable Long id,
@PathVariable String orderId) {
return "User: " + id + ", Order: " + orderId;
}
// @RequestParam - 查询参数
@GetMapping("/search")
public String search(@RequestParam String keyword,
@RequestParam(defaultValue = "1") int page,
@RequestParam(required = false) String sort) {
return "Search: " + keyword + ", Page: " + page + ", Sort: " + sort;
}
// @RequestBody - 请求体(JSON/XML)
@PostMapping("/users")
public User createUser(@RequestBody User user) {
return userService.save(user);
}
// @RequestHeader - 请求头
@GetMapping("/headers")
public String getHeaders(@RequestHeader("User-Agent") String userAgent,
@RequestHeader(value = "X-Custom", defaultValue = "default") String custom) {
return "User-Agent: " + userAgent + ", Custom: " + custom;
}
// @ModelAttribute - 模型属性(表单数据)
@PostMapping("/register")
public String register(@ModelAttribute User user) {
userService.save(user);
return "redirect:/success";
}
}
异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理资源不存在异常
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
// 处理参数验证异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity handleValidationExceptions(MethodArgumentNotValidException ex) {
List errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.toList());
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", "Validation failed", errors);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
// 处理所有其他异常
@ExceptionHandler(Exception.class)
public ResponseEntity handleAllExceptions(Exception ex) {
ErrorResponse error = new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
// 错误响应类
class ErrorResponse {
private String code;
private String message;
private List details;
private LocalDateTime timestamp;
public ErrorResponse(String code, String message) {
this.code = code;
this.message = message;
this.timestamp = LocalDateTime.now();
}
// getter 和 setter 方法
}
静态资源处理
- classpath:/static - 存储 CSS、JS、图片等静态资源
- classpath:/public - 公共静态资源
- classpath:/resources - 资源文件
- classpath:/META-INF/resources - Webjars 资源
# application.properties
spring.web.resources.static-locations=classpath:/static/,file:/opt/files/
spring.mvc.static-path-pattern=/**
# 缓存配置
spring.web.resources.cache.period=3600
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
文件上传
@RestController
public class FileUploadController {
@PostMapping("/upload")
public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.badRequest().body("Please select a file to upload");
}
try {
// 保存文件
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
Path path = Paths.get("uploads/" + fileName);
Files.createDirectories(path.getParent());
Files.write(path, file.getBytes());
return ResponseEntity.ok("File uploaded successfully: " + fileName);
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to upload file: " + e.getMessage());
}
}
// 多文件上传
@PostMapping("/upload-multiple")
public ResponseEntity> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {
List fileNames = new ArrayList<>();
for (MultipartFile file : files) {
if (!file.isEmpty()) {
try {
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
Path path = Paths.get("uploads/" + fileName);
Files.write(path, file.getBytes());
fileNames.add(fileName);
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}
return ResponseEntity.ok(fileNames);
}
}
# 配置文件上传大小限制
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
提示: 这是一个重要的概念,需要特别注意理解和掌握。
注意: 这是一个常见的错误点,请避免犯同样的错误。
评论
请 登录 后发表评论