SpringMVC超详细面试题(附答案)

1、什么是Spring MVC?简单介绍下你对springMVC的理解?
Spring MVC是一个基于Java的实现了MVC设计模式的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
2、什么是MVC?
MVC主要的用途就是对组件之间进行隔离分层。
M:业务逻辑/数据模型
V:视图
C:控制器
3、SpringMVC执行的大体流程是什么?
核心组件 DispatcherServlet 处理整体的流程,处理所有HTTP请求和响应。
(1)浏览器端发起一个请求,先发送到DispatcherServlet。
(2)接收到用户的请求,会查询HandLerMapping找到具体要调用的是谁,然后跳转到指定的控制器。
(3)Controller调用服务方法,Controller方法将业务模型返回的数据和目标视图存放在ModelAndView对象中。
(4)再把ModelAndView对象传给DispatcherServlet,DispatcherServlet会从 ViewResolver中获取请求的定义视图,最后DispatcherServlet将模型数据传递到最终的视图并在浏览器上呈现。
4、SpringMVC执行的详细流程是什么? 答案一
SpringMVC流程
1、 用户发送请求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 Controller执行完成返回ModelAndView。
7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、 ViewReslover解析后返回具体View。
10、 DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户。

5、请解释SpringMVC各常用组件的功能?

常用组件的解释:
1、前端控制器DispatcherServlet(不需要工程师开发),由框架提供
作用:接收请求,响应结果,相当于转发器,中央处理器。有了dispatcherServlet减少了其它组件之间的耦合度。
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。
作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。
2、处理器映射器HandlerMapping(不需要工程师开发),由框架提供
作用:根据请求的url查找Handler
HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3、处理器适配器HandlerAdapter
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
通过扩展处理器适配器,支持更多类型的处理器。
4、处理器Handler(需要工程师开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler。
5、视图解析器View resolver(不需要工程师开发),由框架提供
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。
一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由工程师根据业务需求开发具体的页面。
通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。
6、视图View(需要工程师开发jsp…)
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)
6、SpringMVC执行的详细流程是什么?答案二
核心架构的具体流程步骤如下:
1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);
5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
7、SpringMVC执行的详细流程是什么?答案三
现在我们来看一下这个图的步骤:(可以对比MVC的原理图进行理解)
第一步:用户发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找
第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain)
第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)
第五步:处理器适配器去执行Handler
第六步:Handler执行完给处理器适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView
第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析
第九步:视图解析器像前端控制器返回View
第十步:前端控制器对视图进行渲染
第十一步:前端控制器向用户响应结果

8、解释SpringMVC常用注解的作用?
(1)@Controller注解:用于指示Spring类的实例是一个控制器,使用@Controller注解的类不需要继承特定的父类或者实现特定的接口,相对之前的版本实现Controller接口变的更加简单。而Controller接口的实现类只能处理一个单一的请求动作,而@Controller注解注解的控制器可以同时支持处理多个请求动作,使程序开发变的更加灵活。使用@Controller注解标记的一个类就是一个Spring MVC Controller对象,即:一个控制器类。
(2)@RequestMapping注解:Spring使用扫描机制查找应用程序中所有基于@Controller注解的控制器类,分发处理器会扫描使用了该注解类中的方法,并检测该方法是否使用了@RequestMapping注解,使用@RequestMapping注解的方法才是真正处理请求的处理器。
(3)@RequestParam注解:根据url中的参数名获得参数值。
(4)@RequestBody注解:常用在获得requestbody体中的json字符串转成实体类
(5)@PathVaribale注解:获得URL中路径变量中的值
(6)@RequestHeader注解:获得请求头中属性对应的值
(7)@CookieValue注解:获得cookie值
(8)@SessionAttributes注解:向session中存放数据
(9)@MoelAttribute注解:可以从session中取得数据

以上注解的使用方式请参考如下URL:
https://blog.csdn.net/qian_ch/article/details/73826663

9、SpringMVC控制层类中为什么不能定义实例变量
因为Controller默认单例模式的,高并发下实例变量会出现线程安全问题,值被其它请求所覆盖。

10、SpringMVC中的拦截器和Servlet中的Filter有什么区别?
两者拦截的侧重点是不同的。
SpringMVC中的拦截器是依赖JDK的反射实现的,SpringMVC的拦截器主要是进行拦截请求,通过对Handler进行处理的时候进行拦截,先声明的拦截器中的preHandle方法会先执行,然而它的postHandle方法(他是介于处理完业务之后和返回结果之前)和afterCompletion方法却会后执行,并且Spring的拦截器是按照配置的先后顺序进行拦截的。
而Servlet的Filter是基于函数回调实现的过滤器,Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类)。
SpringMVC中的拦截器侧重于处理SpringMVC框架本身的处理,而Filter过滤器侧重于request和response相关的处理。

11、SpringMVC的优点
(1)可以支持各种视图技术,比如FreeMarker,Thymeleaf,而不仅仅局限于JSP;
(2)与Spring框架集成(如IoC容器、AOP等);
(3)清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。
(4) 支持各种请求资源的映射策略。
(5)它是基于组件技术的,无论控制器和视图,还是业务对象之类的都是 java 组件.并且和 Spring 提供的其他基础结构紧密集成.
(6)不依赖于 Servlet API(目标虽是如此,但是在实现的时候确实是依赖于 Servlet 的)

12、SpringMVC和Struts2的区别有哪些?
(1)SpringMVC的入口是一个Servlet,即前端控制器(DispatchServlet),而Struts2入口是一个Filter过虑器(StrutsPrepareAndExecuteFilter)。
(2)SpringMVC是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例)。Struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
(3)Struts2将传递到View层中的数据默认封装进ValueStack对象中,然后在JSP中从ValueStack中取出数据并显示,而SpringMVC把值默认存放在request中,在JSP中从request中取出数据并显示。

13、SpringMVC怎么样设定重定向和转发的?
(1)转发:return listUserinfo.jsp
(2)重定向:return redirect:listUserinfoController"

14、SpringMVC怎么和AJAX相互调用的?
前端代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="/jquery/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
    
    function login(){
        /**
        * 提交方式一:整个表单的数据提交方式
        */
         //serialize():表单序列化
        var params = $("#loginForm").serialize();
        //post请求,params:请求参数,将数据传到后端,function(result){}:回调函数,接收后端返回的数据,参数名(result)可随便取
        
     $.post("/Jquery/login",params,function(result){
            //因为SpringMVC框架和Jquery框架的联合作用,使得传回来的result保留了原有数据类型
            if(result){//登录成功
                
                window.location.href="http://www.baidu.com";
                
            }else{
                //完全等于  document.getElementById("erSpan").innerHTML = result+":"+"登录失败!";
                $("#erSpan").html(result+":"+"登录失败!");
            }
            
        })
    }
    
    function login2(){
        /**
        *提交方式二:一个个数据上传的方式
        */
        //以下两句相当于 document.getElementById("userName").value;
        var userName = $("#userName").val();
        var pwd = $("#pwd").val();
        
        //写法一:key值必须要加"";
        //var params = {"userName":userName,"pwd":pwd};
        //写法二:
        var params = "userName="+userName+"&pwd="+pwd;
        
        //发送请求到后台
        //如果要传参,直接在第二个参数中传就可以了
        $.post("/Jquery/login",params,function(result){
            //因为SpringMVC框架和Jquery框架的联合作用,使得传回来的result保留了原有数据类型
            if(result){
                window.location.href="http://www.baidu.com"
            }else{
                //完全等于document.getElementById("erSpan").innerHTML = result+":"+"登录失败!";
                $("#erSpan").html(result+":"+"登录失败!");
            }
        }) 
    }
</script>
</head>
<body>
    <span id="erSpan"></span>
    <form id="loginForm" action="/Jquery/login" method="post">
        用户名:<input type="text" name="userName" id="userName" /> <br />
        密码<input type="text" name="pwd" id="pwd" /><br />
        <input type="button" value="ajax表单提交" onclick="login()" />
        <input type="button" value="ajax单独提交" onclick="login2()" />
    </form>
</body>
</html>

后台代码:

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/Jquery")
public class JqueryController {
    /*
     * 注意:如果在浏览器上访问login.html的路径为:IP:端口号/login.html,而这里访问login方法的路径直接为:
            /login,前面没有任何路径,如@RequestMapping("/Jquery"),则会出现406错误
    */
    @RequestMapping("/login")
    @ResponseBody//加上这个注解,return 就不会再跳转页面,只是返回数据(json)
    public Boolean login(String userName,String pwd){
        System.out.println(userName+":"+pwd);
        if("流星".equals(userName) && "456".equals(pwd)){
            return true;
        }
        return false;
    }
    
}

15、如何解决POST请求中文乱码问题,GET的又如何处理呢?
(1)解决post请求乱码问题:
在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8;

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

(2)get请求中文参数出现乱码解决方法有两个:
①修改Tomcat配置文件添加编码与工程编码一致,如下:

建议使用如下办法,因为Tomcat中的配置有的时候没有权限更改。

②另外一种方法对参数进行重新编码:
String userName =
new String(request.getParamter(“userName”).getBytes(“ISO8859-1”),“utf-8”)
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。

16、Spring MVC的异常处理 ?
可以将异常抛给Spring框架,由Spring框架来处理;只需要使用@ExceptionHandler配置异常处理器,在异常处理器中添加视图页面及在视图上显示什么信息即可。
3个示例代码:
(1)案例1

@RestControllerAdvice
public class GlobalControllerAdvice {
    @ExceptionHandler(ValidationException.class) //指定要处理哪一个异常类
    @ResponseStatus(HttpStatus.BAD_REQUEST) //指定要返回那种状态码
    public Map<String,String> validationExceptionHandler(ValidationException exception){
        Map<String,String> map = new HashMap<>();
        map.put("message",exception.getMessage());
        return map;
    }
}

(2)案例2

@RestControllerAdvice //因为都是json格式返回给前端,所以用这个东西
public class ControllerExceptionAdvice {
    @ResponseBody
	@ExceptionHandler(java.lang.Exception.class)
	public JsonResult handleEXCEPTION(){
		return new JsonResult(ResultCode.EXCEPTION, ResultCode.EXCEPTION.msg());
	}

(3)案例3

@RestControllerAdvice
public class BaseController {
    protected Logger logger = LoggerFactory.getLogger(getClass());
    @ExceptionHandler
    public @ResponseBody Object exceptionHandler(Exception exception, HttpServletResponse response) {
        if (exception instanceof BException) {
            exception.printStackTrace();
            logger.error(exception.getMessage());
            return JsonResult.error(((BException) exception).getMsg());
        }else {
            exception.printStackTrace();
            logger.error(exception.getMessage());
            return JsonResult.error("系统发生错误。");
        }
    }
}

17、SpringMVC中控制器的注解一般用那个,有没有别的注解可以替代?
一般用@Controller注解,也可以使用@RestController。
@RestController注解相当于@ResponseBody+@Controller。

18、只想处理get提交的方式怎么配置?
可以在@RequestMapping注解里面加上method=RequestMethod.GET。

19、怎样在方法里面得到request和session?
直接在方法的形参中声明HttpServletRequest和HttpSession。SpringMVC会自动把request和session对象传入。

20、如何实现方法的参数值是来自于URL参数值?
直接在方法的形参里声明这个参数就可以,方法的参数名必须和URL的参数名一样。

21、如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?
直接在方法参数中声明这个对象(ENTITY或DTO),SpringMVC自动会把属性值传递到对象里面。

22、SpringMVC中函数的返回值是什么?
返回值可以有很多类型,有String, ModelAndView。ModelAndView类把视图和数据合并的一起,但一般用String比较好。
(1)String
(2)void
(3)View
(4)ModelAndView (Class)
(5)Model (Interface)
(6)Map
(7)HttpEntity<?> or ResponseEntity<?>
(8)HttpHeaders
以上8个数据类型都可以做为返回值。
23、SpringMVC用什么对象从后台向前台传递数据的?
可以使用ModelAndView,Model,ModelMap或者使用request,前台可以通过el表达式拿到。

24、怎么样把ModelMap里面的数据放入Session里面?
可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。
@SessionAttributes(value={“user1”, “user2”}),会将model或request中属性名为user1和user2的属性添加到session中。

25、SpringMVC里面拦截器是怎么写的:

/**
 * 自定义拦截器
 */
public class MyInterceptor extends HandlerInterceptorAdapter {
	/**
	 * 在请求之前执行
	 * @param request
	 * @param response
	 * @param handler 表示被拦截的请求目标
	 * @return false:拦截请求,终止请求 true:继续执行请求
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
								Object handler) throws Exception {
		//业务逻辑代码编写...(如:解决乱码,权限验证)
		request.setCharacterEncoding("utf-8");
		return true;
	}
	
	/**
	 * @param modelAndView 可以对视图进行操作
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response,
							Object handler, ModelAndView modelAndView) throws Exception {
		//业务逻辑代码编写...(如:操作日志记录,更改视图信息)
	}
	
	/**
	 * @param ex 异常
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
								Object handler, Exception ex) throws Exception {
		//业务逻辑代码编写...(如:,资源销毁,异常处理)
	}
}

a) public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception
该方法在action执行前执行,可以实现对数据的预处理,比如:编码、防重复提交安全控制等。
如果方法返回true,则继续执行action。返回false则拦截请求

b) public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception
该方法在action执行后,生成视图前执行。在这里,我们有机会修改视图层数据。

c) public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
最后执行,通常用于释放资源,处理异常。我们可以根据ex是否为空,来进行相关的异常处理。

26、@RequestMapping注解用在类上面有什么作用
  用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

27、什么是DispatcherServlet以及它有什么作用?
DispatcherServlet是Front Controller前端控制器设计模式的一个实现,它处理对Spring MVC应用程序的所有传入Web请求。前端控制器模式是Web应用程序中的常见模式,其作用是接收所有请求并将其路由到应用程序的不同组件以进行实际处理。
在Spring MVC的情况下,DispatcherServlet将Web请求路由到Spring MVC控制器。
在Spring MVC中,DispatcherServlet用于查找正确的Controler以处理请求,它在处理程序映射的帮助下执行,例如@RequestMapping注释。
它还负责将逻辑视图名称委派给ViewResolver,然后将呈现的响应发送到客户端。

28、类DispatcherServlet如何被web容器所实例化?
DispatcherServlet由Tomcat或Jetty等Servlet容器实例化。必须将DispatcherServlet定义到web.xml文件中。
将load-on-startup标记内容设置为>=0的数,当Spring MVC应用程序部署到Tomcat或任何其他Servlet容器时,当web容器启动时将自动实例化DispatcherServlet。在实例化期间,它会查找文件servlet-name-context.xml,然后初始化此文件中定义的bean。

29、Spring MVC中的root应用程序上下文是什么?怎么装载的?
在Spring MVC中,使用ContextLoaderListener加载的上下文称为“root”应用程序上下文,可以称为根上下文,或父上下文。它属于整个应用程序,而使用DispatcherServlet初始化的应用程序上下文是root上下文的子上下文,两者之间的关系就是父容器与子容器。

30、类ContextLoaderListener的作用是什么?
ContextLoaderListener是一个监听器,监听web容器启动的动作,使用此监听,并且web容器启动后就可以加载并创建ApplicationContext,因此不必编写显式代码来创建它,只需要在web.xml中配置即可。
ContextLoaderListener是在web.xml中配置为监听器的,可以将它放在一个标记中,如下所示:

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

部署Spring MVC Web应用程序时,Servlet容器创建了一个ContextLoaderListener类的实例,该类加载Spring的WebApplicationContext。应用程序上下文是Spring管理bean的一个容器。对于Web应用程序,有一个名为WebAppliationContext的子类。

31、InternalResourceViewResolver有什么作用?
在Spring MVC中,ViewResolver返回View以处理基于逻辑视图名称(由控制器提供)和语言环境输出呈现。这种方式控制器没有耦合到特定的视图技术,例如JSP或FreeMarker,它只返回逻辑视图名称。
InternalResourceViewResolver是在Spring MVC和DispatcherServlet中配置的默认View解析器用它来找到正确的视图。InternalResourceViewResolver用于呈现JSP(JstlView)。
它将前缀和后缀配置为逻辑视图名称,然后生成特定JSP的路径,如下所示:

<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/" />
<property name = "suffix" value = ".jsp" />
</bean >

因此,如果Controller返回"hello"作为逻辑视图名称,则InternalViewResolver将返回/WEB-INF/hello。

发布了37 篇原创文章 · 获赞 54 · 访问量 3163

猜你喜欢

转载自blog.csdn.net/qq_43107323/article/details/104305093