Spring MVC框架面试题

发布于:2024-08-08 ⋅ 阅读:(173) ⋅ 点赞:(0)

目录

一、什么是SpringMVC?简单介绍下你对SpringMVC的理解?

二、SpringMVC的流程?

三、SpringMVC的优点

四、SpringMVC的主要组件

五、SpringMVC怎么样设重定向和转发的?

六、SpringMVC怎么和Ajax相互调用的?

七、如何解决 Post 请求中文乱码问题,Get 的又如何处理呢?

八、SpringMVC的异常处理?

九、SpringMVC的控制器是不是单例模式,如果有,有什么问题,怎么解决?

十、SpringMVC常用的注解有哪些?

十一、SpringMVC种的控制器的注解一般用哪个,有没有别的注解可以替代?

十二、怎样在方法里面得到 Request, 或者 session ?

十三、如果想在拦截的方法里面得到从前台传入的参数,怎么得到?

十四、如果前台有很多个参数传入,并且这些参数都是一个对 象的,那么怎么样快速得到这个对象?

十五、SpringMVC 里面拦截器是怎么写的?

十六、注解原理


一、什么是SpringMVC?简单介绍下你对SpringMVC的理解?

SpringMVC 是一个基于 Java 的实现了 MVC 设计模式的请求驱动类型的轻量级 web 框架,通过把 Model , View , Controller 分离,将 web 层进行职责解耦,把复杂的 web 应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

二、SpringMVC的流程?

( 1 )用户发送请求至前端控制器 DispatcherServlet ;

( 2 ) DispatcherServlet 收到请求后,调用 HandlerMapping 处理器映射器,请求获取 Handle

( 3 )处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet ;

( 4 ) DispatcherServlet 调用 HandlerAdapter 处理器适配器

( 5 ) HandlerAdapter 经过适配调用具体处理器 (Handler ,也叫后端控制器);

( 6 ) Handler 执行完成返回 ModelAndView

( 7 ) HandlerAdapter 将 Handler 执行结果 ModelAndView 返回给DispatcherServIet

( 8 ) DispatcherServlet 将 ModelAndView 传给 ViewResolver 视图解析器进行解析;

( 9 ) ViewResolver 解析后返回具体 View ;

( 10 ) DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)

( 11 ) DispatcherServlet 响应用户。

三、SpringMVC的优点

( 1 )可以支持各种视图技术,而不仅仅局限于 JSP ;

( 2 )与 Spring 框架集成(如 IoC 容器 .AOP 等);

( 3 )清晰的角色分配·前端控制器 (dispatcherServlet) ,请求到处理器映射( handlerMapping), 处理器适配器( HandlerAdapter), 视图解析器( ViewResolver )

( 4 )支持各种请求资源的映射策略。

四、SpringMVC的主要组件

( 1 )前端控制器 DispatcherServlet (不需要程序员开发)

作用:接收请求.响应结果,相当于转发器,有了 DispatcherServlet 就减少了其它组件之间的耦合度。

( 2 )处理器映射器 HandlerMapping (不需要程序员开发)

作用:根据请求的 URL 来查找 Handler

( 3 )处理器适配器 HandlerAdapter

注意:在编写 Handler 的时候要按照 HandlerAdapter 要求的规则去编写这样适配器 HandlerAdapter 才可以正确的去执行 Handlero。

4 )处理器 Handler (需要程序员开发)

( 5 )视图解析器 ViewResolver (不需要程序员开发)

作用·进行视图的解析,根据视图逻辑名解析成真正的视图( view )

( 6 )视图 View (需要程序员开发 jsp )

View 是一个接口,它的实现类支持不同的视图类型 (jsp , freemarker ,pdf 等等)

五、SpringMVC怎么样设重定向和转发的?

( 1 )转发:在返回值前面加 "forward:"',譬如"forward:user.do?name=method4"

( 2 )重定向:在返回值前面加 "redirect:"譬如"redirect:百度一下,你就知道"

六、SpringMVC怎么和Ajax相互调用的?

通过 Jackson 框架就可以把 Java 里面的对象直接转化成 Js 可以识别的 Json对象。具体步骤如下:

( 1 )加入 Jackson.jar

( 2 )在配置文件中配置 json 的映射

( 3 )在接受 AJax 方法里面可以直接返回 Object,List 等,但方法前面要加上@ResponseBody 注解。

@RestController
@RequestMapping("/your-endpoint")
public class YourController {

    @PostMapping
    public ResponseEntity<String> handleAjaxRequest(@RequestBody YourRequestData data) {
        // 处理请求
        String result = processData(data);
        
        // 返回响应
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
    
    private String processData(YourRequestData data) {
        // 处理逻辑
        return "处理结果";
    }
}

七、如何解决 Post 请求中文乱码问题,Get 的又如何处理呢?

( 1 )解决 post 请求乱码问题:

在 web.xml 中配置一个 CharacterEncodingFilter 过滤器,设置成 utf-8;

( 2 ) get 请求中文参数出现乱码解决方法有两个·:

修改 tomcat 配置文件添加编码与工程编码一致,如下:<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port=" 8080 " pr0tocoI="HTTP/1.1" redirectPort= " 8443 "/>

另外一种方法对参数进行重新编码String userName= new String(request.getParamter("userName").getBytes("IS08859-1"),"utf-8")

IS08859 -1 是 tomcat 默认编码,需要将 tomcat 编码后的内容按 utf-8 编码。

八、SpringMVC的异常处理?

答:可以将异常抛给 Spring 框架,由 Spring 框架来处理;我们只需要配置简单的异常处理器,在异常处理器中添视图页面即可。

九、SpringMVC的控制器是不是单例模式,如果有,有什么问题,怎么解决?

答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。

十、SpringMVC常用的注解有哪些?

@RequestMapping :用于处理请求 url 映射的注解,可用于类或方法上。用于类上则表示类中的所有响应请求的方法都是以该地址作为父路径。

@RequestBody :注解实现接收 http 请求的 json 数据,将 json 转换为 java 对象。注解实现将 controller 方法返回对象转化为 json 对象相应给客户。

十一、SpringMVC种的控制器的注解一般用哪个,有没有别的注解可以替代?

一般用@Controller 注解,表示是表现层,不能用别的注解代替。

十二、怎样在方法里面得到 Request, 或者 session ?

在 Spring MVC 中,你可以在控制器的方法参数中直接声明 HttpServletRequestHttpSession 来获取它们。Spring 框架会自动将它们注入到方法中。以下是如何操作的示例:

获取 HttpServletRequest

import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MyController {

    @GetMapping("/example")
    public String handleRequest(HttpServletRequest request) {
        // 使用 request 对象
        String parameter = request.getParameter("paramName");
        
        // ... 你的逻辑代码 ...
        
        return "viewName"; // 返回视图名称
    }
}

获取 HttpSession

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MyController {

    @GetMapping("/example")
    public String handleSession(HttpSession session) {
        // 使用 session 对象
        Object value = session.getAttribute("attributeName");
        
        // ... 你的逻辑代码 ...
        
        return "viewName"; // 返回视图名称
    }
}

十三、如果想在拦截的方法里面得到从前台传入的参数,怎么得到?

通过HttpServletRequest对象

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String parameter = request.getParameter("paramName"); // 获取参数名为paramName的参数值
        // ... do something with the parameter
        return true; // 如果返回true则继续流程,返回false则中断
    }

    // ... implement other methods if needed
}

十四、如果前台有很多个参数传入,并且这些参数都是一个对 象的,那么怎么样快速得到这个对象?

在控制器中使用@RequestBody注解

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/myEndpoint")
public class MyController {

    @PostMapping("/submitData")
    public ResponseEntity<String> submitData(@RequestBody MyObject myObject) {
        // myObject 现在包含了前台传来的所有参数
        // 处理业务逻辑
        return ResponseEntity.ok("Data received");
    }
}

十五、SpringMVC 里面拦截器是怎么写的?

步骤 1: 创建拦截器类

首先,创建一个类实现HandlerInterceptor接口,并重写其中的方法。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyInterceptor implements HandlerInterceptor {

    // 请求处理之前进行调用(Controller方法调用之前)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 你的代码逻辑,例如:权限校验、日志记录等
        // 如果返回true则继续流程,返回false则中断
        return true;
    }

    // 请求处理之后进行调用,但在视图被渲染之前(Controller方法调用之后)
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 你的代码逻辑,可以对ModelAndView进行操作
    }

    // 在整个请求结束之后调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要是用于进行资源清理工作)
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 你的代码逻辑,例如:清理资源、记录日志等
    }
}

步骤 2: 注册拦截器

然后,你需要在Spring MVC的配置中注册这个拦截器。这可以通过XML配置或者Java配置完成。

XML配置方式

在Spring的配置文件中(如springmvc.xml),添加以下配置:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/> <!-- 指定拦截器拦截的路径 -->
        <bean id="myInterceptor" class="com.example.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

Java配置方式

如果你使用Java配置,可以在一个配置类中添加以下内容:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 指定拦截器拦截的路径
    }
}

注意事项

  • preHandle方法返回true时,后续的拦截器和目标Controller才会被执行;返回false时,后续的拦截器和目标Controller不会被执行。
  • postHandle方法在preHandle方法返回true时执行。
  • afterCompletion方法无论preHandle方法返回什么都会执行,通常用于清理资源。

十六、注解原理

注解本质是一个继承了 Annotation 的特殊接口,其具体实现类是 Java 运行时生成的动态代理类。我们通过反射获取注解时,返回的是 Java 运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler 的 invoke 方法。该方法会从 memberValues这个 Map 中索引出对应的值。而 memberValues 的来源是 Java 常量池。


网站公告

今日签到

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