文章目录
Servlet的缺点
- 每编写一个Servlet都需要编写8行
配置文件
。 - 每个Servlet只有一个入口方法,只能处理一个业务。如果处理多个业务需要编写多个Servlet,这样设计模式繁琐。
- servlet
获取参数
时,必须一个一个的获取。并且参数类型必须手动转化。
什么是SpringMVC
SpringMVC是一个前端控制框架,主要用来接收用户提交的参数
和响应数据
,SpringMVC是Spring家族的一大组件。
说说Spring MVC的几个重要组件?
前端控制器
DispatcherServlet
作用:接收请求、响应结果,相当于转发器。处理器映射器
HandlerMapping
作用:根据请求的URL来查找能够处理的Controller。(Handler)处理器适配器
HandlerAdapter
作用:根据请求来查找能够处理该请求的处理器,处理器处理请求代码,返回结果给前端控制器。处理器Handler
:处理请求代码,返回结果。视图解析器
ViewResolver
作用:进行视图解析,将视图的逻辑名解析成真正的视图(view)。
SpringMVC 的工作原理?
步骤:
1.用户向服务器发送请求,请求被 springMVC 前端控制器 DispatchServlet
捕获;
2.前端控制器请求处理器映射器:查询能够处理该请求的Controller
3.将找到的Controller路径返回给前端控制器
.
4.前端控制器请求处理器适配器: 找到能够处理该请求的处理器。
5.处理器
执行请求代码。(controller-service-dao)
6.将处理后的结果和响应页面
封装到ModelAndView对象中,返回给处理器适配器.
7.将ModelAndView对象返回给前端控制器.
8.前端控制器请求视图解析器: 解析View对象,确定是哪个页面。
9.视图解析器
内部拼接,将页面名称
拼接成真实的页面路径
,返回给前端控制器
。(拼接前缀和后缀:View=hello -->(/WEB-INF/hello.jsp))
10.视图渲染(将数据填充到页面中
(request域中)),最后将完整的view展示给用户。
springmvc常用注解?
@Controller:
tomcat启动时,把资源让spring来管理。相当于在 xml 中配置一个 bean。。
@RequestMapping:
用于建立请求URL和请求方法之间的对应关系,可用于类或方法上。
@RequestParam:
用于把请求中指定名称的参数
赋值给控制器中的形参。
@PathVariable
:用于把URL中占位符参数
绑定到控制器中的形参。
@RequestBody:
用于获取请求体的内容。
@ResponseBody
:将 controller 方法返回对象
转为 json
响应给用户。
@ModelAttribute
:该Controller的所有方法在调用前,先执行此
@ModelAttribute方法。
springMVC和struts2的区别有哪些?
(1)springmvc的入口是一个servlet即前端控制器
(DispatchServlet)。而struts2入口是一个filter过虑器
。
(2)springmvc是基于方法开发
,请求参数传递到方法的形参,可以设计为单例或多例。struts2是基于类开发
,请求参数传递到类的属性,只能设计为多例。
(3)springmvc通过参数解析器解析request请求的内容,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后将ModelAndView中的模型数据通过reques域传输到页面。JSP视图解析器默认使用JSTL。Struts采用值栈存储请求和响应的数据,通过OGNL存取数据。
(4)spring MVC和Spring是无缝的。从这个项目的管理和安全
上也比Struts2高。
SpringMVC怎么样设定重定向和转发的?
(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"
(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
@RequestMapping("/testForwardOrRedirect")
public String testForwardOrRedirect(){
System.out.println("testForwardOrRedirect方法执行了······");
//请求的转发
//return "forward:/WEB-INF/pages/success.jsp";
//重定向(关键字,重定向不用加项目名,底层已经帮你加上了)
return "redirect:/index.jsp";
}
简述 redirect 和 forward 区别
(1)转发的特点:forward
① 转发是一次请求,可以使用request对象来共享数据
② 转发地址栏路径不变
③ 转发只能访问当前服务器下的资源,可以访问WEB-INF
(2)重定向的特点:redirect
① 重定向是两次请求。不能使用request对象来共享数据
② 地址栏发生变化
③ 重定向可以访问服务器外部资源,不能访问WEB-INF
Spring MVC怎么得到Request,或者Session?
答:直接在方法的形参中声明request,SpringMVC就自动把request对象传入。
Spring MVC的异常处理 ?
答:可以将异常抛给Spring框架,由Spring框架来处理。我们只需要配置简单的异常处理器
,在异常处理器中添加视图页面
即可。
SpringMvc的Controller是不是单例模式,如果是,有什么问题,怎么解决?
答:是单例模式,所以在多线程访问的时候有线程安全问题,会影响性能的。解决方案是尽量不要在Controller中使用类变量。
- 对于多例情况普通属性是不会共用的,对于静态属性会去共用这个属性。
- 对于单例情况普通属性和静态属性都会被共用。(controller默认为单例)
springmvc
是基于方法开发的,方法里边的形参不会被共享,因此默认是多例。springmvc如果要使用类变量,需要定义为多例的。Struts
是基于类的属性开发的,单例会共享属性,因此单例不安全,所以默认为多例。
对于SpringMVC Controller单例和多例,下面举了个例子说明下。
第一类:类是多例,一个普通属性和一个静态属性
普通属性:0.............静态属性:0
普通属性:0.............静态属性:1
普通属性:0.............静态属性:2
普通属性:0.............静态属性:3
所以说:对于多例情况普通属性是不会共用的,不会产生影响,对于静态属性会去共用这个属性。
第二次:类改为单例
普通属性:0.............静态属性:0
普通属性:1.............静态属性:1
普通属性:2.............静态属性:2
普通属性:3.............静态属性:3
所以说:对于单例情况普通属性和静态属性都会被共用。
第三次:类去掉@Scope注解
结果:
普通属性:0.............静态属性:0
普通属性:1.............静态属性:1
普通属性:2.............静态属性:2
普通属性:3.............静态属性:3
所以说:springmvc默认是单例的。
第四类:另外在其他方法里面打印
跳到别的方法里面也并不会去取初始值,而是再去共用这个属性。
总结
尽量不要在controller里面去定义属性,如果在特殊情况需要定义属性的时候,那么就在类上面加上注解@Scope(“prototype”)改为多例的模式。
以前struts是基于类的属性进行发的,定义属性可以整个类通用,所以默认是多例,不然多线程访问肯定是共用类里面的属性值的,肯定是不安全的。但是springmvc是基于方法的开发,都是用形参接收值,一个方法结束参数就销毁了,多线程访问都会有一块内存空间产生,里面的参数也是不会共用的,所有springmvc默认使用了单例.
所以controller里面不适合在类里面定义属性,只要controller中不定义属性,那么单例完全是安全的。springmvc这样设计主要的原因也是为了提高程序的性能和以后程序的维护只针对业务的维护就行,要是struts的属性定义多了,都不知道哪个方法用了这个属性,对以后程序的维护还是很麻烦的。