Spring MVC 面试题

 2022-08-06
原文作者:Mr'刘 原文地址:https://blog.csdn.net/weixin_56473495/article/details/123665614

1、什么是SpringMVC ?

Spring MVC 是spring框架的一部分(子框架), 是实现对Servlet技术进行封装。

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器 (controller)的缩写,它是一种软件设计典范,是一种软件架构设计分层模式。

Model(模型) 是应用程序中用于处理应用程序数据逻辑的部分。

View(视图) 是应用程序中处理数据显示的部分。

Controller(控制器) 是应用程序中处理用户交互的部分。

最典型的MVC就是JSP + servlet + javabean的模式。

对SpringMVC的理解?

Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无需中间整合层来整合 ,它和Struts2一样都属于表现层的框架。在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

2、SpringMVC 的执行流程?

202208062241295611.png

  1. 用户发送请求至前端控制器DispatcherServlet;
  2. DispatcherServlet收到请求后,调用处理器映射器HandlerMapping,请求获取Handle;
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给前端控制器DispatcherServlet;
  4. DispatcherServlet通过处理器适配器HandlerAdapte调用处理器Handle;
  5. 执行处理器(Handler,也叫后端控制器,需要程序员做处理);
  6. 处理器Handler执行完成返回ModelAndView;
  7. 处理器适配器HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
  8. DispatcherServlet将ModelAndView传给视图解析器ViewReslover进行解析;
  9. 视图解析器ViewReslover解析后返回具体View;
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  11. DispatcherServlet响应用户。

3、Spring MVC 的优点?

  • SpringMVC本身是与Spring框架结合而成的,它同时拥有Spring的优点(例如依赖注入DI和切面编程AOP等)。
  • SpringMVc提供强大的约定大于配置的契约式编程支持,即提供一种软件设计范式,减少软件开发人员做决定的次数,开发人员仅需规定应用中不符合约定的部分。
  • 支持灵活的URL到页面控制器的映射。
  • 可以方便地与其他视图技术(JSP、FreeMarker等)进行整合。由于SpringMVC的模型数据往往是放置在Map数据结构中的,因此其可以很方便地被其他框架引用。
  • 拥有十分简洁的异常处理机制。
  • 可以十分灵活地实现数据验证、格式化和数据绑定机制,可以使用任意对象进行数据绑定操作。
  • 支持RestFul风格。

4、 Spring MVC的主要组件?

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

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

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

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

  • 处理器适配器HandlerAdapter

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

  • 处理器Handler(需要程序员开发)
  • 视图解析器 ViewResolver(不需要程序员开发)

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

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

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

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

  1. 在返回值前面加"forward:"就可以让结果转发,譬如"forward:user.do?name=method4"
  2. 在返回值前面加"redirect:"就可以让返回值重定向,譬如"redirect:百度一下,你就知道"

6、SpringMvc怎么和AJAX相互调用的?

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

  1. 加入Jackson.jar
  2. 在配置文件中配置json的映射
  3. 在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解。

7、Spring MVC 的常用注解有哪些?

@requestMapping:用于请求 url 映射。
@RequestBody: 注解实现接收 http 请求的 json 数据,将 json 数据转换为 java 对象。
@ResponseBody :注解实现将 controller 方法返回对象转化为 json 响应给客户。
@Conntroller:控制器的注解,表示是表现层,不能用用别的注解代替

@Autowire 和 @Resource 的区别?

@Autowire是Spring开发的,而@Resource是jdk开发的

@Autowire是按照类型type来注解的,而@Resource是按照名称来的,如果名称找不到,那么就按照类型type

注意:@Resource 是先按照name来注入的,如果找不到就按照类型注入,不过如果在controller使用的时候,指定了name的值,那么只能按照name来注入,如果找不到name就会报错,如果想要实现先按照name,找不到再按照type,就不要指定name的值。

8、如何解决 get 和 post 乱码问题?

解决 post 请求乱码:在 web.xml 里边配置一个 CharacterEncodingFilter 过滤器并设置编码为 utf-8即可。

1、解决 post 请求乱码:

在 web.xml 里边配置一个 CharacterEncodingFilter 过滤器并设置 编码为 utf-8即可。

2、解决 get 请求乱码:

  1. 修改 tomcat 配置文件添加编码与工程编码一致。
  2. 对参数进行重新编码
    String  userName  =  New String(Request.getParameter(“userName”).getBytes(“ISO8859-1”), “utf-8”);
    --ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。

9、Spring MVC 用什么对象从后台向前台传递数据的?

  • 使用Map、Model 和 ModelMap 的方式,这种方式存储的数据是在request域中
    @RequestMapping("/getUser")
    public String getUser(Map<String,Object> map,Model model,ModelMap modelMap){
        //1.放在map里  
        map.put("name", "xq");
        //2.放在model里,一般是使用这个
        model.addAttribute("habbit", "Play");
        //3.放在modelMap中 
        modelMap.addAttribute("city", "gd");
        modelMap.put("gender", "male");
        return "userDetail";
    }
  • 使用request的方式
    @RequestMapping("/getUser")
    public String getUser(Map<String,Object> map,Model model,
    ModelMap modelMap,HttpServletRequest request){
        //放在request里  
        request.setAttribute("user", userService.getUser());
        return "userDetail";
    }
  • 使用ModelAndView
    @RequestMapping("/getUser")  
    public ModelAndView getUser(ModelAndView modelAndView) {
        mav.addObject("user", userService.getUser());  
        mav.setViewName("userDetail");  
        return modelAndView;  
    }

10、怎么样把ModelMap里面的数据放入session里面?

在类上添加@SessionAttributes注解将指定的Model数据存储到session中。

@SessionAttributes

  1. 默认情况下Spring MVC将模型中的数据存储到request域中。当一个请求结束后,数据就失效了。如果要跨页面使用。那么需要使用到session。而@SessionAttributes注解就可以使得模型中的数据存储一份到session域中。
  2. @SessionAttributes只能定义在Class,interface enum上,作用是将指定的Model中的键值对添加至session中,方便在一个会话中使用。

@SessionAttributes参数

  1. names:这是一个字符串数组。里面应写需要存储到session中数据的名称。
  2. types:根据指定参数的类型,将模型中对应类型的参数存储到session中。
  3. value:其实和上面的names是一样的。
    @SessionAttributes(value={"names"},types={Integer.class})
    @Controller
    public class session{
    
        @RequestMapping("/session")
        public String session(Model model){
            model.addAttributes("names", Arrays.asList("caoyc","zhh","cjx"));
            model.addAttributes("age", 22);
            return "/session";
        }
    }

在上面代码中,在类上添加@SessionAttributes注解,并指定将names名称的Model数据存储到session域中,以及将Integer类型的Model数据存储到session域中。

11、拦截器与过滤器的区别?

拦截器的配置一般在的 SpringMVC 配置文件中,使用Interceptors标签,具体配置如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.LoginInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.AuthInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器(Interceptor) :它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如 动态代理 就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。拦截器可以对静态资源的请求进行拦截处理。

过滤器(Filter) :它依赖于servlet容器。它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。

12、动态代理的两种方式和区别?

JDK动态代理 :利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGlib动态代理 :利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

区别 :JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。