SpringMVC_day01

发布于:2025-03-24 ⋅ 阅读:(30) ⋅ 点赞:(0)

1. SpringMVC 核心概念

  • 作用:简化 Web 开发,实现 MVC 模式,专注于请求处理、数据绑定和响应生成。
  • 核心组件
    • DispatcherServlet:中央控制器,接收所有请求。
    • HandlerMapping:映射请求到具体控制器方法。
    • HandlerAdapter:调用控制器方法并处理返回结果。
    • ViewResolver:解析视图名称,生成最终响应。

2. 入门案例关键点

  • 项目结构
    src/main/java
    ├── com.itheima.controller
    │   └── UserController.java
    ├── com.itheima.config
    │   ├── SpringMvcConfig.java
    │   └── ServletContainersInitConfig.java
    └── pom.xml
    
  • 配置流程
    1. 导入依赖:Spring-webmvc、Servlet API。
    2. 配置类
      @Configuration
      @ComponentScan("com.itheima.controller")
      @EnableWebMvc // 开启 JSON 转换等功能
      public class SpringMvcConfig {}
      
    3. Servlet 初始化类
      public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
          @Override
          protected Class<?>[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
          @Override
          protected String[] getServletMappings() { return new String[]{"/"}; }
      }
      
  • 控制器示例
    @RestController // @Controller + @ResponseBody
    @RequestMapping("/users")
    public class UserController {
        @GetMapping("/{id}")
        public User getUser(@PathVariable Integer id) {
            return new User(id, "张三", 20);
        }
    }
    

下面为你提供一个简单的 SpringMVC 入门案例,这个案例主要实现接收客户端请求并返回响应结果。这里使用 Maven 来管理项目依赖。

步骤 1:创建 Maven 项目

首先,创建一个 Maven Web 项目,在pom.xml文件中添加必要的依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>springmvc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Spring MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.28</version>
        </dependency>
        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>
</project>
步骤 2:配置 web.xml

src/main/webapp/WEB-INF目录下创建web.xml文件,配置DispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置 DispatcherServlet -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-mvc-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
步骤 3:配置 Spring MVC

src/main/webapp/WEB-INF目录下创建spring-mvc-config.xml文件,配置 Spring MVC:

步骤 4:创建控制器

src/main/java/com/example/controller目录下创建HelloController.jav

步骤 5:部署和运行

将项目打包成 WAR 文件并部署到 Servlet 容器(如 Tomcat)中,启动容器。

步骤 6:测试

在浏览器中访问http://localhost:8080/springmvc-demo/hello,你应该能看到Hello, Spring MVC!的响应信息。

3. 请求与响应处理

  • 参数接收

    类型 示例代码 说明
    普通参数 public String save(String name, Integer age) 自动绑定 URL 或表单参数。
    POJO public String save(@RequestBody User user) 接收 JSON 数据,需 @RequestBody
    路径参数 public String delete(@PathVariable Integer id) 匹配 URL 中的 {id}
    日期参数 public String date(@DateTimeFormat(pattern="yyyy-MM-dd") Date date) 自定义日期格式。
  • 响应处理

    • JSON 响应:直接返回对象,依赖 @RestController 或 @ResponseBody
    • 页面跳转:返回视图名(需配置视图解析器)。

4. RESTful 风格开发

  • 核心注解
    • @GetMapping@PostMapping@PutMapping@DeleteMapping
    • @PathVariable 绑定路径参数。
  • 示例
    @PostMapping
    public String addBook(@RequestBody Book book) { /* ... */ }
    
    @DeleteMapping("/{id}")
    public String deleteBook(@PathVariable Integer id) { /* ... */ }
    

5. 查缺补漏

  1. 静态资源处理

    • 需配置 WebMvcConfigurer 放行静态资源:
      @Configuration
      public class WebConfig implements WebMvcConfigurer {
          @Override
          public void addResourceHandlers(ResourceHandlerRegistry registry) {
              registry.addResourceHandler("/static/**").addResourceLocations("/static/");
          }
      }
      
  2. 异常处理

    • 使用 @ControllerAdvice 和 @ExceptionHandler 全局处理异常:
      @ControllerAdvice
      public class GlobalExceptionHandler {
          @ExceptionHandler(Exception.class)
          @ResponseBody
          public Map<String, Object> handleException(Exception ex) {
              return Map.of("code", 500, "msg", "服务器内部错误");
          }
      }
      
  3. 拦截器

    • 实现 HandlerInterceptor 接口,配置拦截路径:
      public class LoginInterceptor implements HandlerInterceptor {
          @Override
          public boolean preHandle(HttpServletRequest request, 
                                  HttpServletResponse response, 
                                  Object handler) {
              // 登录验证逻辑
              return true; // 放行
          }
      }
      
      @Configuration
      public class InterceptorConfig implements WebMvcConfigurer {
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              registry.addInterceptor(new LoginInterceptor())
                      .addPathPatterns("/admin/**"); // 拦截路径
          }
      }
      
  4. 数据验证

    • 使用 @Valid 和 BindingResult 校验请求参数:
      public String save(@Valid @RequestBody User user, BindingResult result) {
          if (result.hasErrors()) {
              return result.getFieldError().getDefaultMessage();
          }
          // 业务逻辑
      }
      
  5. 文件上传

    • 配置 MultipartResolver,使用 @RequestParam("file") MultipartFile file 接收文件。

6. 常见问题与解决方案

  • 404 错误
    • 检查 @RequestMapping 路径是否正确。
    • 确保静态资源路径在 WebMvcConfigurer 中放行。
  • JSON 转换失败
    • 确认 jackson-databind 依赖已添加。
    • 检查 @EnableWebMvc 是否配置。
  • 中文乱码
    • 配置 CharacterEncodingFilter
      @Override
      protected Filter[] getServletFilters() {
          CharacterEncodingFilter filter = new CharacterEncodingFilter();
          filter.setEncoding("UTF-8");
          filter.setForceRequestEncoding(true);
          return new Filter[]{filter};
      }
      

7. 总结

  • 核心流程:请求 → DispatcherServlet → HandlerMapping → 控制器方法 → 响应。
  • 关键注解@RestController@RequestMapping@RequestBody@PathVariable
  • 最佳实践
    • 使用 @RestController 简化 JSON 响应。
    • 分离配置类(SpringMVC 与 Spring 基础配置)。
    • 全局处理异常和拦截器提升代码健壮性。

常见的注解

在 Spring MVC 里,注解的使用能简化开发流程,增强代码的可读性与可维护性。下面为你详细介绍 Spring MVC 中常见的注解。

控制器相关注解

  • @Controller:用来把一个类标记成 Spring MVC 的控制器。此注解会让 Spring 框架识别该类,进而处理客户端的请求。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {
    @RequestMapping("/test")
    @ResponseBody
    public String test() {
        return "Test response";
    }
}
  • @RestController:这是@Controller@ResponseBody的组合注解。当一个类使用@RestController注解时,其所有方法的返回值都会被当作响应体直接返回,常用于构建 RESTful 风格的服务。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {
    @RequestMapping("/restTest")
    public String restTest() {
        return "REST test response";
    }
}

请求映射注解

  • @RequestMapping:能够把 HTTP 请求映射到控制器的方法上。它可对请求的 URL、请求方法(GET、POST 等)、请求参数等进行配置。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class RequestMappingController {
    @RequestMapping(value = "/getData", method = RequestMethod.GET)
    @ResponseBody
    public String getData() {
        return "Data from GET request";
    }

    @RequestMapping(value = "/postData", method = RequestMethod.POST)
    @ResponseBody
    public String postData() {
        return "Data from POST request";
    }
}
  • @GetMapping@RequestMapping(method = RequestMethod.GET)的快捷方式,专门用于处理 HTTP GET 请求。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GetMappingController {
    @GetMapping("/getInfo")
    public String getInfo() {
        return "Info from GET request";
    }
}
  • @PostMapping@RequestMapping(method = RequestMethod.POST)的快捷方式,专门用于处理 HTTP POST 请求。
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PostMappingController {
    @PostMapping("/submitData")
    public String submitData() {
        return "Data submitted successfully";
    }
}
  • @PutMapping@RequestMapping(method = RequestMethod.PUT)的快捷方式,用于处理 HTTP PUT 请求,一般用于更新资源。
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PutMappingController {
    @PutMapping("/updateData")
    public String updateData() {
        return "Data updated successfully";
    }
}
  • @DeleteMapping@RequestMapping(method = RequestMethod.DELETE)的快捷方式,用于处理 HTTP DELETE 请求,通常用于删除资源。
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DeleteMappingController {
    @DeleteMapping("/deleteData")
    public String deleteData() {
        return "Data deleted successfully";
    }
}

请求参数注解

  • @RequestParam:用于从请求的 URL 参数中获取值,并将其绑定到控制器方法的参数上。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestParamController {
    @RequestMapping("/getParam")
    public String getParam(@RequestParam("name") String name) {
        return "Name: " + name;
    }
}
  • @PathVariable:用于从请求的 URL 路径中获取参数值。
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PathVariableController {
    @RequestMapping("/user/{id}")
    public String getUser(@PathVariable("id") int id) {
        return "User ID: " + id;
    }
}
  • @RequestBody:用于将请求体中的数据绑定到控制器方法的参数上,通常用于处理 JSON 或 XML 格式的数据。
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

class User {
    private String name;
    private int age;

    // Getters and setters
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

@RestController
public class RequestBodyController {
    @PostMapping("/addUser")
    public String addUser(@RequestBody User user) {
        return "User added: " + user.getName() + ", Age: " + user.getAge();
    }
}

其他注解

  • @ModelAttribute:有两种用途,一是在方法参数上使用时,可将请求参数绑定到模型对象;二是在方法上使用时,可将该方法的返回值添加到模型中。
  • @SessionAttributes:用于将模型中的属性存储到 HTTP 会话中。
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
@SessionAttributes("userName")
public class SessionAttributesController {
    @RequestMapping("/addSessionAttribute")
    public String addSessionAttribute(Model model) {
        model.addAttribute("userName", "John");
        return "success";
    }

    @RequestMapping("/getSessionAttribute")
    public String getSessionAttribute(@ModelAttribute("userName") String userName) {
        return "User name from session: " + userName;
    }
}
  • @ExceptionHandler:用于处理控制器中抛出的异常。
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExceptionHandlerController {
    @RequestMapping("/throwException")
    public String throwException() {
        throw new RuntimeException("An error occurred");
    }

    @ExceptionHandler(RuntimeException.class)
    public String handleException(RuntimeException e) {
        return "Error: " + e.getMessage();
   

网站公告

今日签到

点亮在社区的每一天
去签到