SpringMVC知识点总结
- 什么是SpringMVC?如何理解Spring MVC?
SpringMVC是属于Spring Framework 生态里面的一个模块。它是在Servlet的基础上构建,并且使用了MVC的模式设计的一个请求驱动型的一个轻量级的Web框架。它的主要目的是简化传统的Servlet+JSP模式下的Web开发方式。
Spring MVC的整个框架的设计是对java Web里面的MVC框架模式做了一些增强和扩展。
主要体现在:
- 把传统的MVC架构里面的Controller控制器做了拆分,分成了前端控制器DispatchServlet和后端控制器Controller。
- 把Model模型拆分成业务层Service和数据访问层Repository。
- 在视图层,可以支持不同的视图,比如Freemark、velocity、JSP等等。
-
Spring MVC的优点有哪些?
- 可以支持多种视图技术,freemark、JSP等等。
- 清晰的角色分配:前端控制器(DispatchServlet),处理器映射器(HandlerMapping),视图解析器(ViewResolver)。
- 容易集成:Spring MVC可以与其他的Spring框架(如Spring IoC和Spring AOP)无缝集成,可以很轻松的创建一个完整的企业级应用程序。
- 有很高的性能:SpringMVC具有很好的性能,因为它支持各种视图解析器和模板引擎,并且可以轻松地集成缓存和CDN等技术。
- 支持各种请求资源策略。
-
Spring MVC的主要组件?
-
前端控制器(DispatchSerlvlet):接收客户端请求,相应结果,相当于一个请求分发器。有了DispatchSevlet就减少了其他组件之间的耦合度。
-
处理器映射器(handlerMapping):根据请求的URL寻找处理器(Handler)
-
处理器适配器(HandlerAdapter)
Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handle
-
处理器(Handler):需要程序员自己编写
-
视图解析器(ViewResolver):进行视图的解析,根据视图逻辑名解析成真正的视图(view)
-
视图View:View是一个接口,它的实现类支持不同的视图类型。
-
-
什么是前端控制器DispatcherServlet?
DispatchServlet是SpringMVC框架中的核心组件之一,它是一个Servlet,用于接收客户端的请求,将其分发给相应的处理器(Handler)进行处理。在Spring MVC中它扮演者控制器角色,负责接收请求并协调请求处理的各个组件,最终将结果返回给客户端。
在Spring MVC中,DIspatchServlet是通过Servlet容器来进行初始化和加载的。当客户端发送请求时,DispatchServlet首先会根据请求的路径和请求方法选择对应的handler进行处理。Handler可以是Controller类中的方法、Restful API、静态文件或者其他类型的处理器。在选择Handler后,DispatcherServlet会将请求的参数、请求头和请求体等信息传递给Handler,并等待Handler返回处理结果。
当Handler返回处理结果后,DispatcherServlet会将结果进行封装,并根据请求的Accept头信息选择对应的视图进行渲染。视图可以是JSP页面、HTML模板、JSON数据或者其他类型的渲染器。最终,DispatcherServlet会将渲染结果返回给客户端。
- 什么是Spring MVC框架的控制器?
控制器提供一个访问应用程序的行为,通常通过服务接口来实现。控制器通过解析用户输入,将其转化为视图呈现给用户的模型。
- Spring MVC的控制器是不是单例模式,如果是,存在什么问题,怎么解决?
Spring MVC的控制器是单例模式,由于控制器是共享的,在多线程的环境下会出现线程安全问题,这里通常还不能使用同步,会影响性能。如果多个请求同时访问同一个控制器实例,可能会导致数据竞争和错误的结果。
- 解决方案:
- 避免在控制器中定义可变状态,如字段或实例变量(类成员变量)。可以使用局部变量代替或者将其参数作为方法参数传递。在 Spring MVC 中,控制器是单例的,因此控制器中的实例变量或类成员变量的值是共享的,因此这些变量的状态是可变的。如果在控制器中定义了可变状态的实例变量或类成员变量,并且在多个线程之间共享,就可能导致出现线程安全问题。
- 如果需要在控制器中使用可变状态,可以使用线程安全的数据结构来管理共享状态,如 ConcurrentHashMap。
- 可以使用 prototype 作用域来创建非单例的控制器实例,这样每次请求都会创建一个新的控制器实例,从而避免线程安全问题。
- 可以在控制器类上添加 @Scope 注解,将控制器的作用域设置为 request 或 session,从而每个请求或会话都将创建一个新的控制器实例,避免线程安全问题。
- 描述Spring MVC的工作流程和DispatcherServlet的工作流程。
- 用户发送请求到前端控制器DispacherServlet
- 前端控制器接收到请求之后,调用HandlerMapping处理器映射器,请求获取Handler处理器。
- 处理器映射器HandlerMapping收到 前端控制器DispatchServlet的请求后,会根据前端控制器传递过来的 URL生成处理器对象以及处理器拦截器(有则生成),将其一并返回给前端控制器DispatchSerlvet;
- **前端控制器DispatchServlet**调用 处理器适配器HandlerAdapter;
- 处理器适配器HandlerAdapter经过适配调用具体的 处理器Handler(后端控制器);
- Handler后端控制器 执行完成后将 ModelAndView返回给 处理器适配器HandlerAdapter,然后,**HandlerAdapter(处理器适配器)**将其(ModelAndView)返回给 前端控制器DispatchServlet;
- 前端控制器DispatchServlet将ModelAndView 传给**ViewResolver(视图解析器)**进行解析;
- ViewResolver(视图解析器)将其解析后的结果 View返回给 前端控制器DispatchServlet;
- 前端控制器DispatchServlet对 View进行最后的渲染视图(也就是模型数据填充到视图中);
- 前端控制器DispatchServlet响应给用户。
由以上可以看见 前端控制器DispatchServlet几乎贯穿所有的Spring MVC的执行流程,可以看出是及其重要的。
- MVC是什么?MVC设计模式的好处有哪些?
MVC是一种软件设计模式,它代表Model-View-Controller(模型-视图-控制器),MVC模式的目的是将应用程序的不同方面分开,便于更好的项目管理和修改代码。
该软件设计模式将应用程序分为三个重要的组件:
- 模型(Model):代表应用程序的持久层和业务逻辑层。模型负责管理应用程序的状态,并且通常与数据库或者其他存储系统进行 数据交互;
- 视图(View):代表的是应用程序的用户界面。视图主要负责呈现模型中的数据以及处理用户输入数据。
- **控制器(Controller):**接收用户输入,进行对业务逻辑层的调用,实现数据模型的更新。控制器充当模型和视图之间的中介,使它们保持解耦,不直接依赖彼此。
MVC模式可以是代码更加的容易维护和拓展,该模式的运用使得应用程序的不同层面分离开组成组件,使每个组件只专注于自己的职责。在应用程序需要拓展/更改时。只需要关注所需要更改/拓展相应的组件即可。
MVC设计模式的好处:
- 分离关注点:MVC将应用程序分为三个主要组件:模型、视图和控制器。
- 更好的可维护性:由于MVC模式将应用程序分离为三个独立的组件,这样可以更轻松地进行单元测试和调试。这种可维护性有助于确保应用程序具有更高的质量和可靠性。
- 更好的可扩展性:MVC模式使得应用程序更容易扩展和更改,因为每个组件都是独立的。
- 更好的可重用性:由于MVC模式将应用程序分解为三个独立的组件,这使得这些组件可以在其他应用程序中重复使用。这样可以加快应用程序开发速度,并减少代码的重复。
- 更好的团队协作:由于MVC模式的分离性,不同的开发人员可以同时工作在应用程序的不同组件上。这种协作方式有助于提高开发人员之间的协作效率。
从以上的MVC的有点来看,使用该开发模式,有比较有效的确保应用程序的质量和可靠性。
- 注解原理是什么(需要更深入了解)?
注解是一种元数据,它提供了关于程序元素(例如类、方法、字段)的额外信息。注解通常是使用@符号和元素名称一起来表示,如@Deprecated、@Override;
在Java中,注解是通过Java的反射机制来实现的,注解的本质是继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。通过反射获取注解是,返回的是Java运行时生成的代理对象。通过代理对象调用自定义注解的方法。
会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。
- Spring MVC常用的注解有哪些?
@RequestMapping
:用于请求处理URL映射的注解,可用于类或方法上方。用于类上表示类中所有响应请求的方法都是以该路径为父路径。
@RequstBody
:将接收的JSON数据转化为Java 对象。
@ResponseBody
:注解实现将Controller方法返回的对象转化为JSON对象响应给客户端。
- SpringMVC中的控制器的注解一般用哪几个?有没有别的可以替代?
一般用@Controller
注解,也可以使用@RestController
,@RestController
注解相当于@ResponseBody
+@Controller
。
- @Controller注解的作用是什么?
在Spring MVC中,控制器Controller负责 处理由前端控制器DispatchServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model,在Spring MVC中定义一个控制器类很简单,只需要在类的上方加上@Controller
。然后再把Model返回给View进行展示。然后使用@RequestMapping
和@RequestParam
等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。
Controller不会直接依赖于HttpServletRequest
和HttpServletResponse
等HttpServlet对象,它们可以通过Controller的方法参数灵活的获取。
@Controller
用于标记在一个类上,使用它标记的类就是一个Spring MVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping
注解。@Controller
只是定义了一个控制器类,而使用@RequestMapping
注解的方法才是真正处理请求的处理器。单单使用@Controller
标记在一个类上还不能真正意义上的说它就是Spring MVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理。有两种方式:
- 在Spring MVC 的配置文件中定义MyController 的bean 对象。
- 在Spring MVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。
- @RequestMapping注解的作用是什么?
RequestMapping
是一个用于处理请求地址映射的注解,可用于类或者方法上。用于类上表示类中所有的响应方法请求方法都是以该地址作为父路径。
RequestMapping
有六个属性:
Value
:指定请求的实际地址,指定地址可是是URI Temple模式。method:指定请求类型。GET、POST、PUT、DELETE等;
consumes:制定处理请求提交的内容类型(Content-Type),例如application/json,html/text等。
produces:指定犯规类型,只有request请求投中的(Accept)类型包含该指定类型才进行处理。
params:指定request中必须包含某些指定参数才进行处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
- @ResponseBody注解的作用是什么?
用于将Controller中的方法返回的对象,通过适当的HttpConvert转换为指定格式后,写入Response对象的body数据区。
返回的不是http标签的页面,而是其他某种格式的数据时使用
- @PathVariable和@RequestParam的区别是什么?
用于接收路径上的变量值,可以通过@PathVariale
来获取@RequstMappung(Value="/page/{id}"),method=RequstMethod.GET
)
@RequestParam用来获得静态的URL请求入参 spring注解时action里用到。
- Spring MVC与Struts2相同点和不同点是什么?
相同点:
都是基于mvc的表现层的框架,都是用于web项目的开发。
不同点:
1、前端控制器不一样。Spring MVC的前端控制器是servlet:DispatchServlet。struts2的前端控制器是filter:StrutsPrepareExcutorFilter。
2、请求参数的接收方式不一样。Spring MVC接收的参数是以方法形参的方式,基于方法的开发,线程安全,可以设计为单例或者多例的开发,推荐使用单例模式的开发(执行效率更高),默认就是单例开发模式。struts2是通过类的成员变量接收请求的参数,是基于类的开发,线程不安全,只能设计为多例的开发。
3、Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,Spring MVC通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。
4、与spring整合不一样。Spring MVC是spring框架的一部分,不需要整合。在企业项目中,Spring MVC使用更多一些 。
-
Spring MVC是怎样设定重定向和转发的?
- 转发:在返回值前面加上“forward:”,例如“forward:user.do?name=method4"
- 重定向:在返回值前面加上“redirect:”,例如“redirect:http://www.bai.com"
-
Spring MVC怎么和AJAX相互调用的?
通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下 :
- 加入Jackson依赖
- 在配置文件中配置json的映射
- 在接受Ajax的方法里可以直接返回Object,List等,方法上需要加上
@ResponseBody
注解。
-
如何解决POST请求中文乱码问题,GET的又如何处理?
-
解决POST中文乱码问题,可以通过在web.xml配置一个编码过滤器,来处理,使其编码为UTF-8。
-
GET请求在Tomcat8之后做了处理,不会导致乱码问题。如果是低版本的话有一下两种解决方式。
-
修改tomcat配置文件添加编码与工程编码一致
-
另外一种方法对参数进行重新编码:
String userName = new String(request.getParamter(“userName”).getBytes(“ISO8859-1”),“utf-8”)
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。
-
-
-
Spring MVC的异常处理是如何处理的?
可以将异常抛给Spring框架,有Spring框架来处理;只需要配置简单的异常处理器,在异常处理器中添加视图界面即可。
- 如果在拦截请求中,我想拦截get方式提交的方法,怎么配置?
在@RequestMapping注解里面加上method=RequestMethod.GET。
- 怎么在方法里面得到Request,或者Session?
在方法形参里直接声明requset或者Session,Spring MVC就会自动的吧request对象传入。
- 如果想在拦截器的方法里面得到从前台传入的参数,怎么得到?
直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样。
- 如果在前台有很多的参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?
接在方法中声明这个对象,Spring MVC就自动会把属性赋值到这个对象里面 。
- Spring MVC中函数的返回值是什么?
返回值可以有很多类型,有String, ModelAndView。ModelAndView类把视图和数据都合并的一起的,但一般用String比较好。
- Spring MVC用什么对象从后台向前台传送数据的?
通过ModelMap对象,可以在这个对象里面调用put方法,把对象加到里面,前台就可以通过el表达式拿到。
- 怎么样把ModelMap里面的数据放入Session里面?
在类上方加上 @SessionAttributes
注解,里面包含的字符串就是要放入的key。
- Spring MVC里面的拦截器是怎么写的?
有两种写法,一种是实现HandlerIntercepor接口,另一种是继承适配器类,接着在接口的方法当中,实现处理逻辑;然后在Spring MVC的配置文件里配置拦截器即可。
- 介绍一下WebApplicationContext?
WebapplicationContext 继承了applicationContext 并增加了一些WEB应用必备的特有功能,它不同于一般的applicationContext ,因为它能处理主题,并找到被关联的servlet。
y。
- Spring MVC里面的拦截器是怎么写的?
有两种写法,一种是实现HandlerIntercepor接口,另一种是继承适配器类,接着在接口的方法当中,实现处理逻辑;然后在Spring MVC的配置文件里配置拦截器即可。
- 介绍一下WebApplicationContext?
WebapplicationContext 继承了applicationContext 并增加了一些WEB应用必备的特有功能,它不同于一般的applicationContext ,因为它能处理主题,并找到被关联的servlet。