《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括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层开发。
- 其核心思想是将请求处理、数据模型和视图渲染分离,提高代码的可维护性和扩展性。
核心组件
- DispatcherServlet:前端控制器,负责接收所有请求并分发到相应的组件(如处理器映射器、适配器等)。
- HandlerMapping:处理器映射器,根据请求URL查找对应的处理器(Handler)。
- HandlerAdapter:处理器适配器,适配不同类型的处理器(如Controller),调用其处理方法。
- Handler(Controller):处理器,业务逻辑处理的核心,接收请求并返回模型数据。
- ModelAndView:封装处理结果的数据模型(Model)和视图(View)信息。
- ViewResolver:视图解析器,根据视图名称解析为具体的视图对象(如JSP、Thymeleaf等)。
- View:视图,负责将模型数据渲染为响应结果(如HTML、JSON等)。
67. Spring MVC的工作流程是怎样的?
原理说明
Spring MVC的工作流程围绕DispatcherServlet展开,通过多个组件协同完成请求处理,具体步骤如下:
工作流程
- 用户发送请求:客户端(如浏览器)发送HTTP请求到Web服务器,请求被DispatcherServlet接收。
- DispatcherServlet调用HandlerMapping:DispatcherServlet根据请求URL,通过HandlerMapping查找对应的Handler(处理器)。
- HandlerMapping返回Handler:HandlerMapping将找到的Handler(如Controller的方法)返回给DispatcherServlet。
- DispatcherServlet调用HandlerAdapter:DispatcherServlet通过HandlerAdapter适配该Handler,准备调用其处理方法。
- HandlerAdapter调用Handler处理请求:HandlerAdapter调用Handler的具体方法(如Controller中的@RequestMapping标注的方法),执行业务逻辑。
- Handler返回ModelAndView:Handler处理完成后,返回封装了模型数据(Model)和视图名称(View)的ModelAndView对象。
- DispatcherServlet调用ViewResolver:DispatcherServlet将ModelAndView中的视图名称传递给ViewResolver,解析为具体的View对象。
- ViewResolver返回View:ViewResolver将解析后的View对象返回给DispatcherServlet。
- DispatcherServlet渲染视图:DispatcherServlet调用View的渲染方法,将Model中的数据填充到视图中,生成响应内容(如HTML)。
- 响应客户端:DispatcherServlet将渲染后的结果返回给客户端,完成请求处理。
68. 请解释DispatcherServlet的作用。
原理说明
- DispatcherServlet 是Spring MVC的前端控制器(Front Controller),是整个Spring MVC流程的核心,负责协调所有组件完成请求处理。
- 它统一接收所有HTTP请求,通过分发机制将请求传递给对应的处理器,并整合处理结果返回给客户端,降低了组件之间的耦合度。
主要作用
- 接收请求:作为Web应用的入口,接收客户端发送的所有HTTP请求(如GET、POST等)。
- 请求分发:根据请求URL,通过HandlerMapping查找对应的处理器(Handler),并通过HandlerAdapter调用处理器的方法。
- 协调组件:整合HandlerMapping、HandlerAdapter、ViewResolver等组件,确保请求处理流程的有序执行。
- 处理结果返回:将处理器返回的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-Type、Authorization)。 - 示例:
@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. 定义拦截器(实现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) |