Skip to content

03-SpringMVC

对应原始资料:springMvc基础springmvc高级

一、SpringMVC 是什么

SpringMVC 是 Spring 的 Web 模块,基于 MVC 模式 + Servlet 实现的请求驱动 Web 框架。

M:Model   业务数据
V:View    视图(JSP / Thymeleaf / JSON)
C:Controller 控制器,处理请求

二、请求处理流程(重点)

浏览器请求

DispatcherServlet(前端控制器,核心)

HandlerMapping        ← 根据 URL 找到对应 Controller 方法

HandlerAdapter        ← 反射调用 Controller 方法

Controller 方法

返回 ModelAndView / 字符串 / 对象

ViewResolver(视图解析器)/ HttpMessageConverter(JSON)

渲染 / 写回响应

三、快速入门(SpringBoot 风格)

现在大多直接用 SpringBoot,无需 web.xml。这里给出最简形式。

java
@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    // GET /users/1
    @GetMapping("/{id}")
    public User getById(@PathVariable Integer id) {
        return userService.findById(id);
    }

    // GET /users?page=1&size=10
    @GetMapping
    public List<User> list(@RequestParam(defaultValue = "1") int page,
                           @RequestParam(defaultValue = "10") int size) {
        return userService.list(page, size);
    }

    // POST /users,Body 是 JSON
    @PostMapping
    public User add(@RequestBody User user) {        // @RequestBody 把 JSON 转对象
        userService.add(user);
        return user;
    }

    @PutMapping
    public void update(@RequestBody User user) { userService.update(user); }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable Integer id) { userService.delete(id); }
}

四、常用注解

注解作用
@Controller声明控制器(返回视图)
@RestController@Controller + @ResponseBody(返回数据)
@RequestMapping类/方法映射,可指定 method
@GetMapping/@PostMapping/@PutMapping/@DeleteMappingRESTful
@RequestParam获取查询参数 / 表单参数
@PathVariable获取路径中的占位变量
@RequestBody获取请求体(JSON)
@RequestHeader获取请求头
@CookieValue获取 Cookie
@ModelAttribute模型属性

五、RESTful 风格

操作方法URL示例
查列表GET/users
查单个GET/users/{id}
新增POST/users
修改PUT/users/{id}
删除DELETE/users/{id}

用 HTTP 方法表示动作,URL 表示资源,无状态。

六、请求与响应

1. 日期处理

java
@GetMapping
public User get(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate birthday) { }

2. 响应 JSON

  • 返回对象 + @RestController,Spring 用 Jackson 自动转 JSON。
  • 字段命名策略:@JsonProperty / 全局 PropertyNamingStrategy

3. 自定义响应结构(统一返回)

java
@Data
public class Result<T> {
    private Integer code;
    private String msg;
    private T data;
    public static <T> Result<T> ok(T data) { ... }
    public static <T> Result<T> fail(int code, String msg) { ... }
}

七、静态资源与拦截器

1. 静态资源

SpringBoot 默认把 /static/public/resources/META-INF/resources 下的文件作为静态资源。

2. 拦截器(HandlerInterceptor)

java
public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object h) {
        Object user = req.getSession().getAttribute("user");
        if (user == null) {
            resp.sendRedirect("/login");
            return false;
        }
        return true;
    }
}

@Configuration
public class WebConfig implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry r) {
        r.addInterceptor(new LoginInterceptor())
         .addPathPatterns("/**")
         .excludePathPatterns("/login", "/css/**", "/js/**");
    }
}

拦截器是 SpringMVC 的,Filter 是 Servlet 的。拦截器只拦 Controller 方法,Filter 能拦所有请求。

八、全局异常处理

java
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public Result handleBiz(BusinessException e) {
        return Result.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result handleAll(Exception e) {
        log.error("系统异常", e);
        return Result.fail(500, "系统繁忙");
    }
}

声明式异常处理,避免每个方法 try/catch。

九、数据校验(Hibernate Validator)

java
@PostMapping
public User add(@Validated @RequestBody User user) { }

class User {
    @NotBlank(message = "姓名不能为空")
    private String name;

    @Min(value = 0, message = "年龄非法")
    private Integer age;

    @Email(message = "邮箱格式错误")
    private String email;
}

// 校验失败会被全局异常处理中的 MethodArgumentNotValidException 捕获

十、文件上传/下载

java
@PostMapping("/upload")
public String upload(MultipartFile file) throws IOException {
    String name = file.getOriginalFilename();
    file.transferTo(new File("D:/upload/" + name));
    return "ok";
}

配置上传大小限制(SpringBoot application.yml):

yaml
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 100MB

十一、跨域(CORS)

java
@CrossOrigin(origins = "*")
@RestController
public class UserController { }

// 或全局
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    public void addCorsMappings(CorsRegistry r) {
        r.addMapping("/**").allowedOriginPatterns("*").allowedMethods("*").allowCredentials(true);
    }
}

练习建议

  1. 用 SpringBoot 搭一个用户 CRUD(RESTful)。
  2. 加统一返回 Result<T> 和全局异常处理。
  3. @Valid 校验参数。
  4. 写一个登录拦截器,未登录拦截。
  5. 实现头像上传接口。