手写springMVC框架: 项目地址:gitee.com/xuzhun/hand…
介绍:
1、请求通过继承httpservlet可以接收到
2、包的扫描通过annotaion里面的方法判断类上是否有该注解,如果有的话,执行ioc创建对象和对象依赖注入
3、构造一个HandlerMapping处理器映射器,将配置好的url和Method建立映射关系,完成请求的初始化。
springMVC源码分析:
什么是springmvc:
SpringMVC是一种基于 Java 的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring框架的一个模块
它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。
MVC的全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码,将众多的业务逻辑聚集到一个部件里面,在需要改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑,达到减少编码的时间。(也就是前后端分离)
V即View视图是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式。(也就是通过http请求,向服务端发送请求,并返回数据)
M即model模型是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。(也就是处理请求的业务模块)
C即controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。(对请求的分发和返回时,视图的调用)
springmvc的工作流程:(这里的核心是前端控制器,负责请求的接受,交给处理器映射器,获得执行处理器适配器的执行,将发挥的数据分发给视图解析器,渲染后,负责数据返回) 1.用户点击某个请求路径,发起一个request请求,此请求会被前端控制器处理。(前端控制器统一处理分发和数据的返回) 2.前端控制器请求处理器映射器去查找Handler。可以依据注解或者XML配置去查找。(查找handler处理拦截业务) 3.处理器映射器根据配置找到相应的Handler(可能包含若干个Interceptor拦截器),返回给前端控制器。(拦截器起着全局的作用,可以配置权限等功能) 4.前端控制器请求处理器适配器去执行相应的Handler处理器(常称为Controller)(处理器适配器主要是处理具体的业务的分发) 5.处理器适配器执行Handler处理器 6.Handler处理器执行完毕之后会返回给处理器适配器一个ModelAndView对象(SpringMVC底层对象,包括Model数据模型和View视图信息) 7.处理器适配器接收到Handler处理器返回的ModelAndView后,将其返回给前端控制器。(返回) 8.前端控制器接收到ModelAndView后,会请求视图解析器(ViewResolver)对视图进行解析。(将处理好的数据,进行视图解析) 9.视图解析器根据View信息匹配到相应的视图结果,反馈给前端控制器。 10.前端控制器收到View具体视图后,进行视图渲染,将Model中的模型数据填充到View视图中的request域,生成最终的视图(View)。 11.前端控制器向用户返回请求结果。
优点: SpringMVC本身是与Spring框架结合而成的,它同时拥有Spring的优点(例如依赖注入DI和切面编程AOP等)。 SpringMVc提供强大的约定大于配置的契约式编程支持,即提供一种软件设计范式,减少软件开发人员做决定的次数,开发人员仅需规定应用中不符合约定的部分。 支持RestFul风格。
.Spring MVC的主要组件? 前端控制器:其作用是接收用户请求,然后给用户反馈结果。它的作用相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。 处理器映射器:其作用是根据请求的URL路径,通过注解或者XML配置,寻找匹配的处理器信息。 处理器适配器:其作用是根据映射器处理器找到的处理器信息,按照特定规则执行相关的处理器(Handler)。 处理器:其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至ModelAndView对象中。 视图解析器:其作用是进行解析操作,通过ModelAndView对象中的View信息将逻辑视图名解析成真正的视图View(如通过一个JSP路径返回一个真正的JSP页面)。 视图:View是一个接口,实现类支持不同的View类型(JSP、FreeMarker、Excel等)。
SpringMVC和Struts2的区别有哪些? SpringMVC的入口是一个Servlet,也就是前端控制器(DispatcherServlet),而Struts2的入口是一个Filter (StrutsPrepareAndExecuteFilter)。 SpringMVC是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例)。struts2是基于类开发,请求参数传递到类的成员属性,只能设计为多例。 SpringMVC通过参数解析器将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用JSTL。Struts2采用值栈存储请求和响应的数据,通过OGNL存取数据。
7.SpringMVC怎么样设定重定向和请求转发? 我们先说说请求转发与重定向的区别:
请求转发与重定向的区别 请求转发在服务器端完成的;重定向是在客户端完成的。 请求转发的速度快;重定向速度慢。 请求转发的是同一次请求;重定向是两次不同请求。 请求转发不会执行转发后的代码;重定向会执行重定向之后的代码。 请求转发地址栏没有变化;重定向地址栏有变化。
8.当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理?
在方法上加@ResponseBody注解,表示该方法的返回值不管是什么类型,都会返回JSON格式的数据。
把原来Controller类上的@Controller注解替换为@RestController注解。@RestController = @Controller + @ResponseBody,表明该Controller类所有的方法都返回JSON格式的数据(没有加@RequestMapping注解的方法除外)。
加入@ResponseBody注解就能返回JSON格式数据的原因是:SpringMVC提供的HttpMessageConverter自动转为JSON ,如果使用了Jackson或者Gson,不需要额外配置就可以自动返回JSON了,因为框架帮我们提供了对应的HttpMessageConverter ,如果使用了Alibaba的Fastjson的话,则需要自己手动提供一个相应的 HttpMessageConverter的实例。
对于post请求,在过滤器上,加入一个解码的配置
修改tomcat或者代码的编码类型
如何解决单例的线程安全问题
常用的注解:
@ResponseBody
@ResponseBody把Java对象转化为json对象,这种方式用于Ajax异步请求,返回的不是一个页面而是JSON格式的数据。
@PathVariable
@PathVariable用于接收uri地址传过来的参数,Url中可以通过一个或多个{Xxx}占位符映射,通过@PathVariable可以绑定占位符参数到方法参数中,在RestFul接口风格中经常使用。
例如:请求URL:http://localhost/user/21/张三/query
(Long类型可以根据需求改变为String或int,SpringMVC会自动做转换)
@RequestParam @RequestParam用于将请求参数映射到控制器方法的形参上,有如下三个属性
value:参数名。 required:是否必需,默认为true,表示请求参数中必须包含该参数,如果不包含抛出异常。 defaultValue:默认参数值,如果设置了该值自动将required设置为false,如果参数中没有包含该参数则使用默认值。 示例:@RequestParam(value = “pageNum”, required = false, defaultValue = “1”)
13.SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代?
一般使用@Controller注解标识控制器。
也可以使用@RestController注解替代@Controller注解,@RestController相当于@ResponseBody+@Controller,表示控制器中所有的方法都返回JSON格式数据,一般不使用其他注解标识控制器。
如何使用拦截器 创建一个类实现接口HandlerInterceptor
controller将数据返回给前台的方式有三个
Map、Model和ModelMap
map方法,将返回的数据放在model中
存放在request中
ModelMap中: