Spring MVC基础(面试)
一、上来就是什么是Spring MVC?
首先,Spring MVC 就是一个MVC 框架,可以帮助我们更简洁的进行web 的开发,天生与Spring 框架集成。通过把Module、View、Controller 分离,将web 层职责进行解耦,方便组内人员之间的配合。
二、Spring MVC 的流程
- 客户端发送请求,直接到DispatcherServlet(它的作用就是接收响应请求);
- DispatcherServlet 根据请求信息调用HandlerMapping,解析请求对应的Handler;
- 解析到Handler 后开始由HandlerAdapter 适配器处理(Handler 也就是我们说的Controller 控制器);
- HandlerAdapter 会根据Handler调用真正的Handler 处理器处理请求,并处理相应的业务;
- 处理完业务返回一个ModuleAndView 对象,Module 是返回的数据对象,View 是逻辑上的View;(还可以返回String类型)
- DispatcherServlet 把ModuleAndView 交由ViewResolver 视图解析器处理,ViewResolver 会根据逻辑View 查找到实际的View;
- DispatcherServlet 会把返回的Module 交由View 进行渲染;
- 把view 返回给请求者。
3. Spring MVC 和Struts2 有什么区别?
- Spring MVC 的核心是基于Servlet 即DispatcherServlet。
Struts2 的核心是基于Filter 即StrutsPreparedAndExecuteFilter。 - Spring MVC 是基于类中的方法开发的,传递参数到方法的形参上,所以可以是单例模式也可以是多例模式。
Struts2 是基于类开发的,传递的参数通过类的属性传递,所以只能设计成多例的。 - Spring MVC 由request 来解析请求内容,然后由其内部的getParameter 给方法中的形参赋值,再把后台处理过的数据通过ModuleAndView 对象存储,Module 存储数据,View存储返回的页面,再把对象通过request 传递给页面。
Struts2 采用的是值栈存储请求以及响应数据,OGNL 存取数据。
4. Spring MVC 怎样设置重定向和转发?
- 重定向:在返回值前面添加redirect
- 转发:在返回值前面添加forward
5. Spring MVC 是怎样和Ajax 交互的?
Jackson 框架可以把Java 里面的对象直接转换成js 能识别的json 对象。
- 导入Jackson jar包;
- 配置文件中配置json 的映射;
- 方法里面可以直接返回Object、list 等,但是要在方法上面加@ResponseBody 注解。
6. 如何解决get、post 中文乱码的问题?
-
解决get 请求:
方式一:Tomcat 默认编码是 ISO-8859-1,所以可以通过修改tomcat 配置编码为utf-8 处理,但不建议;
方式二:将请求的数据从ISO-8859-1 转换成utf-8 编码即可。 -
解决post 请求:
直接对Request 对象设置编码格式为utf-8。
7. Spring MVC 如何向前端传递数据?
- 使用Module 对象(常用)。 如:module.addAttribute(“user”, user);
- 使用HttpServletRequest。如:request.setAttribute(“user”, user);
- 使用Map。如:map.put(“names”, Arrays.asList(“caoyc”,“zhh”,“cjx”));
8. Spring MVC 拦截器怎么写?
拦截器:在一个请求发生前,发生时,发生后都可以对请求拦截。
作用:权限认证、解决乱码、操作日志记录、性能监控、异常处理等。
自定义拦截器:
-
继承HandlerInterceptorAdapter 类
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 该方法在action 执行之前执行,可以实现对数据的预处理(如:编码;防止重复提交安全控制) //如果方法返回true,则继续执行action。返回false 则拦截请求。 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //在action 执行后执行,生成视图前执行。在这里有机会修改视图层数据 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //最后执行,通常释放资源,处理异常。 //可以根据ex 是否为空来进行相应的的异常处理 }
- 单个拦截器的执行流程
- 单个拦截器的执行流程
-
多个拦截器的执行流程(Interceptor1拦截器配置在前)
-
注册拦截器(在XML 文件中配置)
//拦截单个bean <mvc:interceptors> <bean id="myInterceptor" class="com.admol.web.MyInterceptor" /> </mvc:interceptors> //拦截部分指定请求 <mvc:interceptors> <!-- path:需要拦截的请求,不写时会拦截所有请求 --> <mvc:mapping path="/*.htm" /> <bean id="myInterceptor" class="com.admol.web.MyInterceptor" /> </mvc:interceptors> //多个拦截器 <mvc:inteceptors> <bean id="myInterceptor1" class="com.admol.web.MyInterceptor1" /> <bean id="myInterceptor2" class="com.admol.web.MyInterceptor2" /> </mvc:inteceptors>
-
其它实现方式
实现接口:HandlerInterceptor
实现接口:WebRequestInterceptor
9. 过滤器怎么写?
- 实现Filter 接口
import javax.servlet.*;
import java.io.IOException;
public class Handler implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
10. 过滤器与拦截器的区别
- 过滤器
优点: 依赖于Servlet 容器,在实现上基于回调函数,可以几乎所有的请求进行过滤。
缺点: 过滤器实例只能在容器初始化时调用一次。如修改字符编码;在过滤器中修改HttpServletRequest 的一些参数(低俗文字、危险文字)。 - 拦截器
优点: 依赖于web 框架,在实现上是基于Java 反射机制,属于面向切面编程的一种运用。由于是基于web 框架的调用,因此可以使用依赖注入进行一些业务操作,同时一个拦截器实例在controller 生命周期内可以多次调用。
缺点: 只能对controller 进行拦截,对一些比如访问静态资源的请求是无法拦截的。
11. Spring MVC 与Spring
1. Spring 容器和Spring MVC 容器的配置
- Spring 框架整个核心概念中,容器是核心思想,就是用来管理bean 的整个生命周期,但是在一个项目中容器不可能只有一个,Spring 可以包含多个容器,而且容器包含上下层关系。
- 常见场景:一个项目中引入了Spring 和Spring MVC 两个框架。Spring 是根容器,Spring MVC 是子容器。Spring MVC 可以访问Spring 容器中的Bean,Spring 不能访问Spring MVC 中的bean,如果配置不当常常会出现奇怪的问题:如Controller 方法无法拦截,Bean 被多次加载等问题。
- 一般这样明确边界:Spring 根容器负责所有其他非Controller 的Bean 的注册,Spring MVC 只负责Controller 相关的bean 注册。
2. Spring 容器与SpringMVC 容器的联系与区别
- ContextLoadListener 中创建Spring 容器主要用于整个web 程序需要共享的组件,比如Dao、数据库的ConnectionFactory等。
- DispatcherServlet 创建的Spring MVC 容器主要用于和该Servlet 相关的一些组件,比如Controller、ViewResolver 等。
3. ServletContext(Servlet 上下文) 和Spring MVC 的关系
- 服务器会为每一个工程创建一个对象即ServletContext,这个对象是全局唯一的,且工程中所有Servlet 共享这个ServletContext。
- Spring 启动的过程就是Servlet IoC 容器启动的过程,对于web 程序而言,IoC 容器的启动过程即使建立上下文的过程,为后面的Spring IoC 容器提供宿主环境。