Spring面试题及详细答案 125道(66-75) -- Spring MVC篇1

Spring面试题及详细答案 125道(66-75) -- Spring MVC篇1

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。

前后端面试题-专栏总目录

一、本文面试题目录

66. 什么是Spring MVC?它的核心组件有哪些?

原理说明
  • Spring MVC 是Spring框架的一个模块,用于构建Web应用程序,基于MVC(Model-View-Controller)设计模式,通过分离模型、视图和控制器,实现关注点分离,简化Web层开发。
  • 其核心思想是将请求处理、数据模型和视图渲染分离,提高代码的可维护性和扩展性。
核心组件
  1. DispatcherServlet:前端控制器,负责接收所有请求并分发到相应的组件(如处理器映射器、适配器等)。
  2. HandlerMapping:处理器映射器,根据请求URL查找对应的处理器(Handler)。
  3. HandlerAdapter:处理器适配器,适配不同类型的处理器(如Controller),调用其处理方法。
  4. Handler(Controller):处理器,业务逻辑处理的核心,接收请求并返回模型数据。
  5. ModelAndView:封装处理结果的数据模型(Model)和视图(View)信息。
  6. ViewResolver:视图解析器,根据视图名称解析为具体的视图对象(如JSP、Thymeleaf等)。
  7. View:视图,负责将模型数据渲染为响应结果(如HTML、JSON等)。

67. Spring MVC的工作流程是怎样的?

原理说明

Spring MVC的工作流程围绕DispatcherServlet展开,通过多个组件协同完成请求处理,具体步骤如下:

工作流程
  1. 用户发送请求:客户端(如浏览器)发送HTTP请求到Web服务器,请求被DispatcherServlet接收。
  2. DispatcherServlet调用HandlerMapping:DispatcherServlet根据请求URL,通过HandlerMapping查找对应的Handler(处理器)。
  3. HandlerMapping返回Handler:HandlerMapping将找到的Handler(如Controller的方法)返回给DispatcherServlet。
  4. DispatcherServlet调用HandlerAdapter:DispatcherServlet通过HandlerAdapter适配该Handler,准备调用其处理方法。
  5. HandlerAdapter调用Handler处理请求:HandlerAdapter调用Handler的具体方法(如Controller中的@RequestMapping标注的方法),执行业务逻辑。
  6. Handler返回ModelAndView:Handler处理完成后,返回封装了模型数据(Model)和视图名称(View)的ModelAndView对象。
  7. DispatcherServlet调用ViewResolver:DispatcherServlet将ModelAndView中的视图名称传递给ViewResolver,解析为具体的View对象。
  8. ViewResolver返回View:ViewResolver将解析后的View对象返回给DispatcherServlet。
  9. DispatcherServlet渲染视图:DispatcherServlet调用View的渲染方法,将Model中的数据填充到视图中,生成响应内容(如HTML)。
  10. 响应客户端:DispatcherServlet将渲染后的结果返回给客户端,完成请求处理。

68. 请解释DispatcherServlet的作用。

原理说明
  • DispatcherServlet 是Spring MVC的前端控制器(Front Controller),是整个Spring MVC流程的核心,负责协调所有组件完成请求处理。
  • 它统一接收所有HTTP请求,通过分发机制将请求传递给对应的处理器,并整合处理结果返回给客户端,降低了组件之间的耦合度。
主要作用
  1. 接收请求:作为Web应用的入口,接收客户端发送的所有HTTP请求(如GET、POST等)。
  2. 请求分发:根据请求URL,通过HandlerMapping查找对应的处理器(Handler),并通过HandlerAdapter调用处理器的方法。
  3. 协调组件:整合HandlerMapping、HandlerAdapter、ViewResolver等组件,确保请求处理流程的有序执行。
  4. 处理结果返回:将处理器返回的ModelAndView通过ViewResolver解析为视图并渲染,最终将响应结果返回给客户端。
配置示例(web.xml)
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value> <!-- Spring MVC配置文件路径 -->
    </init-param>
    <load-on-startup>1</load-on-startup> <!-- 启动时初始化 -->
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern> <!-- 拦截所有请求 -->
</servlet-mapping>

69. 如何在Spring MVC中配置视图解析器?

原理说明
  • 视图解析器(ViewResolver) 用于将处理器返回的视图名称(如“index”)解析为具体的视图对象(如JSP文件路径、Thymeleaf模板等),简化视图路径的配置。
  • 常见的视图解析器有InternalResourceViewResolver(用于JSP)、ThymeleafViewResolver(用于Thymeleaf)等。
配置示例
1. 基于XML配置(InternalResourceViewResolver)
<!-- spring-mvc.xml -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 视图前缀:指定视图文件的目录 -->
    <property name="prefix" value="/WEB-INF/views/" />
    <!-- 视图后缀:指定视图文件的扩展名 -->
    <property name="suffix" value=".jsp" />
</bean>
  • 若处理器返回视图名称“index”,则解析为/WEB-INF/views/index.jsp
2. 基于Java配置(ThymeleafViewResolver)
@Configuration
@EnableWebMvc
public class SpringMv***onfig implements WebMv***onfigurer {

    // 配置Thymeleaf视图解析器
    @Bean
    public ViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine);
        resolver.setCharacterEncoding("UTF-8");
        return resolver;
    }

    // 配置Thymeleaf模板引擎
    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(templateResolver);
        return engine;
    }

    // 配置Thymeleaf模板解析器
    @Bean
    public ITemplateResolver templateResolver() {
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/WEB-INF/templates/"); // 模板前缀
        resolver.setSuffix(".html"); // 模板后缀
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setCharacterEncoding("UTF-8");
        return resolver;
    }
}

70. @Controller和@RestController的区别是什么?

原理说明
  • 两者都是Spring MVC中用于标识控制器(Controller) 的注解,但功能不同,主要区别在于对响应的处理方式。
区别对比
特性 @Controller @RestController
响应处理 需要通过视图解析器渲染视图(如JSP),或使用@ResponseBody返回数据。 无需额外注解,默认将方法返回值直接作为响应体(等效于@Controller + @ResponseBody)。
适用场景 用于返回视图(如HTML页面)的场景。 用于RESTful API,返回JSON、XML等数据的场景。
底层实现 仅标识为控制器,需配合@ResponseBody返回数据。 @Controller@ResponseBody的组合注解。
示例代码
1. @Controller示例
@Controller
public class PageController {

    // 返回视图(通过视图解析器渲染)
    @RequestMapping("/index")
    public String index() {
        return "index"; // 视图名称,解析为具体页面(如index.jsp)
    }

    // 配合@ResponseBody返回数据
    @RequestMapping("/data")
    @ResponseBody
    public String getData() {
        return "Hello, @Controller with @ResponseBody";
    }
}
2. @RestController示例
@RestController // 等效于@Controller + @ResponseBody
public class ApiController {

    // 直接返回数据(无需@ResponseBody)
    @RequestMapping("/api/user")
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("Spring");
        return user; // 返回JSON格式数据(需配置消息转换器)
    }
}

71. @RequestMapping注解的作用是什么?它的常用属性有哪些?

原理说明
  • @RequestMapping 用于映射HTTP请求到控制器的方法,是Spring MVC中最核心的请求映射注解。
  • 可标注在类或方法上:标注在类上时,为该类所有方法的请求路径添加前缀;标注在方法上时,指定具体的请求路径。
常用属性
属性名 作用 示例
value/path 指定请求的URL路径(两者等效),支持数组(匹配多个路径)。 @RequestMapping(value = "/user")
method 指定请求的HTTP方法(如GET、POST),可通过RequestMethod枚举指定。 @RequestMapping(method = RequestMethod.GET)
params 限制请求必须包含指定的参数,支持表达式(如param1=value!param2)。 @RequestMapping(params = "id=1")
headers 限制请求必须包含指定的请求头。 @RequestMapping(headers = "Content-Type=application/json")
consumes 限制请求的Content-Type(如application/json)。 @RequestMapping(consumes = "application/json")
produces 限制响应的Content-Type(如application/json)。 @RequestMapping(produces = "application/json")
示例代码
@RestController
@RequestMapping("/api") // 类级别路径前缀
public class UserController {

    // 匹配GET请求:/api/user/{id}
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public User getUser(@PathVariable Integer id) {
        return new User(id, "User" + id);
    }

    // 匹配POST请求:/api/user,且Content-Type为application/json
    @RequestMapping(value = "/user", method = RequestMethod.POST, consumes = "application/json")
    public String addUser(@RequestBody User user) {
        return "User added: " + user.getName();
    }

    // 匹配多个路径和方法
    @RequestMapping(value = {"/info", "/detail"}, method = {RequestMethod.GET, RequestMethod.POST})
    public String getInfo() {
        return "Info";
    }
}
简化注解

Spring提供了简化的HTTP方法注解(基于@RequestMapping):

  • @GetMapping:等效于@RequestMapping(method = RequestMethod.GET)
  • @PostMapping:等效于@RequestMapping(method = RequestMethod.POST)
  • 同理还有@PutMapping@DeleteMapping@PatchMapping

72. Spring MVC中如何接收请求参数?(如@RequestParam、@PathVariable、@RequestBody等)

原理说明

Spring MVC提供了多种注解用于接收请求参数,适用于不同的参数传递方式(如URL路径、请求头、请求体等)。

常用参数接收方式
1. @RequestParam:接收URL查询参数或表单参数
  • 用于获取?key=value形式的参数(如/user?id=1&name=test)。
  • 示例:
    @GetMapping("/user")
    public String getUser(
        @RequestParam Integer id, // 必传参数,若未传则报错
        @RequestParam(required = false) String name, // 非必传参数
        @RequestParam(defaultValue = "10") Integer age // 默认值
    ) {
        return "id: " + id + ", name: " + name + ", age: " + age;
    }
    
2. @PathVariable:接收URL路径中的参数
  • 用于获取REST风格URL中的参数(如/user/1中的1)。
  • 示例:
    @GetMapping("/user/{id}/{name}")
    public String getUserByPath(
        @PathVariable Integer id,
        @PathVariable String name
    ) {
        return "Path id: " + id + ", name: " + name;
    }
    
3. @RequestBody:接收请求体中的数据
  • 用于接收JSON、XML等格式的请求体数据,通常配合POST、PUT等方法使用。
  • 示例:
    @PostMapping("/user")
    public String addUser(@RequestBody User user) {
        // User类需有id、name等字段及getter/setter
        return "Added user: " + user.getName();
    }
    
    • 需配置消息转换器(如MappingJackson2HttpMessageConverter)以支持JSON解析。
4. @RequestHeader:接收请求头参数
  • 用于获取请求头中的信息(如Content-TypeAuthorization)。
  • 示例:
    @GetMapping("/header")
    public String getHeader(@RequestHeader("Content-Type") String contentType) {
        return "Content-Type: " + contentType;
    }
    
5. @CookieValue:接收Cookie参数
  • 用于获取请求中的Cookie值。
  • 示例:
    @GetMapping("/cookie")
    public String getCookie(@CookieValue("sessionId") String sessionId) {
        return "SessionId: " + sessionId;
    }
    
6. 实体类接收参数
  • 直接使用实体类接收多个参数,参数名需与实体类字段名一致。
  • 示例:
    @PostMapping("/user/form")
    public String addUserByForm(User user) { // User有id、name、age字段
        return "User: " + user.getId() + ", " + user.getName();
    }
    

73. @RequestParam和@PathVariable的区别是什么?

原理说明

两者均用于接收请求参数,但适用的参数传递方式和场景不同,核心区别在于参数的位置。

区别对比
特性 @RequestParam @PathVariable
参数位置 位于URL查询字符串中(如?id=1&name=test)。 位于URL路径中(如/user/1/test)。
适用场景 用于接收表单提交、GET请求的查询参数等。 用于RESTful风格的URL,标识资源的唯一标识。
参数格式 键值对形式(key=value)。 嵌入URL路径中,无显式键名。
URL示例 http://example.***/user?id=1 http://example.***/user/1
是否必传 默认必传(可通过required=false设置非必传)。 默认必传(路径中必须包含该参数)。
示例代码
@RequestParam示例
// 请求URL:/user?userId=100&userName=test
@GetMapping("/user")
public String getUser(
    @RequestParam("userId") Integer id, // 映射查询参数userId到id变量
    @RequestParam("userName") String name
) {
    return "id: " + id + ", name: " + name; // 输出:id: 100, name: test
}
@PathVariable示例
// 请求URL:/user/100/test
@GetMapping("/user/{userId}/{userName}")
public String getUserByPath(
    @PathVariable("userId") Integer id, // 映射路径参数userId到id变量
    @PathVariable("userName") String name
) {
    return "id: " + id + ", name: " + name; // 输出:id: 100, name: test
}

74. Spring MVC中如何处理文件上传?

原理说明

Spring MVC通过MultipartResolver组件处理文件上传,需配置该组件并使用MultipartFile接收上传的文件。常见的MultipartResolver实现为***monsMultipartResolver(基于Apache ***mons FileUpload)和StandardServletMultipartResolver(基于Servlet 3.0+的内置文件上传支持)。

实现步骤
1. 配置MultipartResolver
基于XML配置(StandardServletMultipartResolver)
<!-- spring-mvc.xml -->
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
    <!-- 可选:设置默认编码 -->
    <property name="defaultEncoding" value="UTF-8" />
</bean>

<!-- 在web.xml中配置DispatcherServlet的文件上传参数 -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <multipart-config>
        <location>/tmp/upload</location> <!-- 临时文件存储路径 -->
        <max-file-size>10485760</max-file-size> <!-- 单个文件最大大小(10MB) -->
        <max-request-size>52428800</max-request-size> <!-- 请求总大小(50MB) -->
    </multipart-config>
</servlet>
基于Java配置
@Configuration
@EnableWebMvc
public class SpringMv***onfig implements WebMv***onfigurer {

    @Bean
    public MultipartResolver multipartResolver() {
        StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
        resolver.setDefaultEncoding("UTF-8");
        return resolver;
    }

    // 配置DispatcherServlet的文件上传参数(需在Servlet初始化时设置)
    @Bean
    public ServletRegistrationBean<DispatcherServlet> dispatcherServlet() {
        ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(
            new DispatcherServlet(), "/"
        );
        MultipartConfigElement multipartConfig = new MultipartConfigElement(
            "/tmp/upload", // 临时路径
            10485760, // 单个文件最大10MB
            52428800, // 总请求最大50MB
            0 // 内存缓冲区大小(0表示使用默认值)
        );
        registration.setMultipartConfig(multipartConfig);
        return registration;
    }
}
2. 编写文件上传控制器
@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String uploadFile(
        @RequestParam("file") MultipartFile file, // 接收上传的文件
        @RequestParam("description") String description
    ) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return "请选择文件";
        }

        try {
            // 获取文件名
            String fileName = file.getOriginalFilename();
            // 定义文件存储路径
            String filePath = "/path/to/upload/directory/";
            File dest = new File(filePath + fileName);
            // 确保目录存在
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            // 保存文件
            file.transferTo(dest);
            return "文件上传成功:" + fileName + ",描述:" + description;
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败:" + e.getMessage();
        }
    }

    // 处理多文件上传
    @PostMapping("/upload/multiple")
    public String uploadMultipleFiles(@RequestParam("files") List<MultipartFile> files) {
        for (MultipartFile file : files) {
            // 处理逻辑同单文件上传
            if (!file.isEmpty()) {
                // 保存文件...
            }
        }
        return "多文件上传完成";
    }
}
3. 前端表单示例(HTML)
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="text" name="description" placeholder="文件描述" />
    <button type="submit">上传</button>
</form>
  • 注意:表单的enctype必须设置为multipart/form-data,否则无法正确上传文件。

75. 如何在Spring MVC中实现拦截器?拦截器的作用是什么?

原理说明
  • 拦截器(Interceptor) 是Spring MVC提供的用于拦截请求的组件,类似于过滤器(Filter),但属于Spring容器管理,可更方便地访问Spring上下文资源。
  • 拦截器主要用于在请求处理的前置、后置、完成后执行额外逻辑,如日志记录、权限验证、性能监控等。
拦截器的作用
  1. 请求前置处理:如验证用户登录状态、记录请求开始时间。
  2. 请求后置处理:如记录响应数据、修改模型数据。
  3. 请求完成后处理:如记录请求耗时、释放资源。
  4. 中断请求流程:如验证失败时,直接返回错误响应,阻止请求到达处理器。
实现步骤
1. 定义拦截器(实现HandlerInterceptor接口)
public class LogInterceptor implements HandlerInterceptor {

    // 请求处理前调用(返回true则继续流程,false则中断)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle:请求路径" + request.getRequestURI() + "开始处理");
        // 示例:验证登录(若未登录则重定向到登录页)
        if (request.getSession().getAttribute("user") == null) {
            response.sendRedirect("/login");
            return false;
        }
        return true;
    }

    // 请求处理后、视图渲染前调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle:请求处理完成,准备渲染视图");
    }

    // 整个请求完成后调用(包括视图渲染)
    @Override
    public void after***pletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("after***pletion:请求全部完成");
    }
}
2. 注册拦截器
基于XML配置
<!-- spring-mvc.xml -->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 拦截的路径(/**表示所有请求) -->
        <mvc:mapping path="/**"/>
        <!-- 排除的路径(不拦截登录相关请求) -->
        <mvc:exclude-mapping path="/login"/>
        <mvc:exclude-mapping path="/register"/>
        <!-- 拦截器实例 -->
        <bean class="***.example.interceptor.LogInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
基于Java配置
@Configuration
@EnableWebMvc
public class SpringMv***onfig implements WebMv***onfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器
        registry.addInterceptor(new LogInterceptor())
                .addPathPatterns("/**") // 拦截所有路径
                .excludePathPatterns("/login", "/register"); // 排除登录和注册路径
    }
}
拦截器与过滤器的区别
特性 拦截器(Interceptor) 过滤器(Filter)
所属框架 Spring MVC Servlet规范
执行时机 在DispatcherServlet之后,处理器之前。 在请求进入Servlet容器之后,DispatcherServlet之前。
功能范围 可访问Spring容器中的Bean,更灵活。 仅依赖Servlet API,功能相对基础。
适用场景 业务逻辑相关(如权限、日志)。 通用功能(如编码转换、跨域处理)。

二、125道Spring面试题目录列表

文章序号 Spring面试题125道
1 Spring面试题及详细答案125道(01-15)
2 Spring面试题及详细答案125道(16-25)
3 Spring面试题及详细答案125道(26-45)
4 Spring面试题及详细答案125道(46-65)
5 Spring面试题及详细答案125道(66-75)
6 Spring面试题及详细答案125道(76-90)
7 Spring面试题及详细答案125道(91-110)
8 Spring面试题及详细答案125道(111-125)
转载请说明出处内容投诉
CSS教程网 » Spring面试题及详细答案 125道(66-75) -- Spring MVC篇1

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买