springMVC

1. MVC思想的演变:

JavaWeb与MVC

  JavaWeb的经历了JSP Model1、JSP Model1二代、JSP Model2三个时期。

JSP Model1第一代
      JSP Model1是JavaWeb早期的模型,它适合小型Web项目,开发成本低!Model1第一代时期,服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。

JSP Model1第二代

  JSP Model1第二代有所改进,把业务逻辑的内容放到了JavaBean中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让JSP做了过多的工作,JSP中把视图工作和请求调度(控制器)的工作耦合在一起了。

JSP Model2
JSP Model2模式已经可以清晰的看到MVC完整的结构了。

l  JSP:视图层,用来与用户打交道。负责接收用来的数据,以及显示数据给用户;

l  Servlet:控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图;

l  JavaBean:模型层,完成具体的业务工作,例如:开启、转账等。

 

 好处在于其中的controller和view的方式可以改变而不影响后面的model层的业务;

JavaWeb经典三层框架
我们常说的三层框架是由JavaWeb提出的,也就是说这是JavaWeb独有的!

所谓三层是表述层(WEB层)、业务逻辑层(Business Logic),以及数据访问层(Data Access)。

l  WEB层:包含JSP和Servlet等与WEB相关的内容;

l  业务层:业务层中不包含JavaWeb API,它只关心业务逻辑;

l  数据层:封装了对数据库的访问细节;

2.SpringMVC的核心组件

 中央处理器、key-value结构找到对应的处理器、适配转换成需要的方法、解析业务返回的页面字符串名称、页面渲染

3.SpringMVC的请求过程

1.客户端往后端发送请求;

2.DispatcherServlet进行请求筛选,主要筛选两种请求:① *.do ② 带/的请求,DispatcherServlet对请求URL(统一资源定位符)进行解析,得到URI(请求资源标识符)

3.因为还需要对响应的请求进行拦截,所以请求HanderMapping ,是一个Key-Value的结构,返回一个包含拦截器和处理器的复合对象HandlerExcutionChain;

4.由于需要对HandlerExcutionChain转换成handler,采用适配器模式进行一次转换handlerAdaptor

5.请求相应的handler,业务处理后返回相应的页面名称和数据

6.请求viewResolver对返回的数据和页面进行组合,返回view对象(ViewResolver接口定义了如何通过view 名称来解析对应View实例的行为,即:如何把控制器返回的“视图名 字符串” 解析为View实例,并渲染为HTML、PDF后推向浏览器);

7.请求view返回页面;(View接口表示一个响应给用户的视图,例如jsp文件,pdf文件,html文件等)

  1. DispatcherServlet会加载所有的viewResolver到一个list中,并按照优先级进行解析。

    注意:①order中的值越小,优先级越高。

    ②而id为viewResolver的viewResolver的优先级是最低的。

  2. 如果某个解析器没有找到合适的视图,Spring会在上下文中寻找是否配置了其它的解析器。 如果有,它会继续进行解析,否则,Srping会抛出一个Exception

4. SpringMVC 的常用注解有哪些?

     1. @PathVariable用于获取路径参数,@RequestParam用于获取查询参数

     2. @RequestBody. 用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的 body 中的 json 字符串转换为 java 对象。

一个请求方法只可以有一个@RequestBody,但是可以有多个@RequestParam@PathVariable

    3.  @RequestMapping :用于处理 URL 映射的的注解,既可用于类上,也可用于方法上,当作用于类上时则表示当前类中的所有响应方法都是以这个 url 作为父路径;

    4. @ResponseBody :将 Java 对象转为 json 格式的数据;

    5.  @RestController 和 @Controller

  1. Controller 返回一个页面:
    单独使用 Controller 不加 @ResponseBody 使用的话就要经过视图解析流程 (ViewResolve),最后返回给到前端一页面,这种情况属于比较传统的 Spring MVC 应用,对应前后端不分离的情况;
  2. @RestController只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中,这种情况属于 RESTful Web服务,这也是目前日常开发所接触的最常用的情况(前后端分离)。
  3. 项目中的实际使用情况:在进行用户密码验证时,返回验证的错误类型,前段显示alarm;

5 . 如何解决 POST 请求和 GET 请求中文乱码问题?

  1. 解决 POST 请求乱码问题:在 web.xml 中配置一个 CharacterEncodingFilter 过滤器,设置成 utf-8 ;
  2. GET 请求中出现中文乱码,讲真在url 中传递中文,就不是什么明智之举,最好不要这用做!
    但是事情已经发生了,总得要解决的:
    1. 修改 Tomcat 配置文件;
    2. 在拼接 url 的时候先做一个编码工作,然后将编码后生成的 url 进行拼接,之后再发送请求,然后再服务端拿到数据后做一次反编码的工作;
    3. 最好就是定义一个字典,在发送 url 的get 请求之前先查询一下要拼接的 中文 字段对应的字典值,然后用字典值进行传输,完事了再在服务端做解析;

6. SpringMVC 制器是不是单例模式,如果是,有什么问题,怎么解决?

是单例模式,之前在 Spring 篇章里面有说过控制层和Service 层以及 DAO 层一般是无状态的实例,不涉及数据的增删改等操作,只有简单的查询操作,那么就是线程安全的,所以解决方案就是:在控制器里面不要写可变的状态量,如果需要这些可变的状态量,那么可以通过 ThreadLocal 进行解决,为每个线程提供一个独立的变量副本,进行数据操作;

7.SpringMVC 怎么样设定重定向和转发的?

  1. 转发:在返回值前面加:“forward”–> "forword:index.do?name=2"
  2. 重定向:在返回值前面加:“redirect” –> “redirect:http://www.baidu.com”

转发可以携带参数、不改变原来的url、一般在服务器的内部页面间转发;

重定向不可以携带参数、产生新的url请求、可以在服务器外部页面进行请求;

8.拦截器和过滤器的区别?

参与流程:

Filter->Interceptor.preHandle->Handler->Interceptor.postHandle->Interceptor.afterCompletion->Filter

实现方式:

filter:自定义类 实现 filter接口,重写init 、dofilter、destroy方法

interceptor: 自定义类实现 handlerInterceptor接口,重写prehandle、posthandle、aftercomplation方法

注册方式

filter注册方式:

1.webfilter过滤+@ServletComponentScan注解开启;@order+@component可以决定优先顺序但是指定的webfilter过滤会失效;

  • 精确过滤匹配 ,比如/index.jsp /myservlet1
  • 后缀过滤匹配,比如.jsp、.html、*.jpg
  • 通配符过滤匹配/**,表示拦截所有。

2.@configuration+@Bean

public FilterRegistrationBean<AuthFilter> RegistAuth(){}可以设置优先级,同时设置过滤url

interceptor注册方式:

@configuration,实现webmvcConfigurer接口,并重写 addInterceptors方法。可以设置优先级,同时设置过滤url

执行顺序:

filter(默认按照名称的字母先后顺序执行),除非指定;

interceptor(默认按照加载先后顺序执行),除非指定;

方法执行:

filter主要是在dofilter中执行,同时结尾调用filterchain.dofilter执行下一个过滤器;

interceptor:prehandle:调用执行器之前执行;posthandle调用执行器之后执行但在渲染之前;aftercomponent,再回送请求之前;

执行顺序:

1. posthandle、aftercomponent都是prehandle的倒序

2.prehandle没通过不执行其他的两个方法;

3.多个拦截器任何一个没通过,所有的posthandle都不会执行

4.prehandle执行且通过,才会有aftercomponent;

使用目的:

过滤器应用场景

  • 过滤敏感词汇(防止sql注入)
  • 设置字符编码
  • URL级别的权限访问控制
  • 压缩响应信息

拦截器应用场景

拦截器本质上是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:

  • 登录验证,判断用户是否登录。
  • 权限验证,判断用户是否有权限访问资源,如校验token
  • 日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
  • 处理cookie、本地化、国际化、主题等。
  • 性能监控,监控请求处理时长等。
  • 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)

拦截器和过滤器的区别
1.过滤器是servlet中的对象,  拦截器是框架中的对象
2.过滤器实现Filter接口的对象, 拦截器是实现HandlerInterceptor
3.过滤器是用来设置request,response的参数,属性的,侧重对数据过滤的
  拦截器是用来验证请求的,能截断请求。
4.过滤器是在拦截器之前先执行的。
5.过滤器是tomcat服务器创建的对象
  拦截器是springmvc容器中创建的对象
6.过滤器是一个执行时间点。
  拦截器有三个执行时间点
7.过滤器可以处理jsp,js,html等等
  拦截器是侧重拦截对Controller的对象。 如果你的请求不能被DispatcherServlet接收, 这个请求不会执行拦截器内容
8.拦截器拦截普通类方法执行,过滤器过滤servlet请求响应

9.  SpringMVC 怎么和AJAX相互调用的?

通过 Jackson 框架可以将 Java 中的对象直接转换为 json 对象:

  1. 加入 Jackson.jar 包
  2. 在配置文件中配置 json 的映射
  3. 在接受 ajax 方法里面可以直接返回对象,但是需要使用 @ResponseBody 注解;

10. 怎样在方法里面得到Request,或者Session?

直接在方法的形参中声明 request,SpringMVC 就自动把 request 对象传入。

11. 如果想在拦截的方法里面得到从前台传入的参数,怎么得到?

直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样。

12. 如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?

直接在方法形参中声明这个对象,SpringMVC 就自动会把属性赋值到这个对象里面。

13. SpringMVC 中函数的返回值是什么?

返回值可以有很多类型,有String,ModelAndView。ModelAndView类把视图和数据都合并的一起的,但一般用String比较好。

14. SpringMVC 用什么对象从后台向前台传递数据的?

  1. 将数据绑定到 request
  2. 返回 ModelAndView;
  3. 通过ModelMap对象,可以在这个对象里面调用put方法,把对象加到里面,前端就可以通过el表达式拿到。
  4. 绑定数据到 Session中;

15.两个方法的映射能否处理相同的url?

1. 同样的URL,不同的Method(Get、Put、Post、Delete)会被映射到各自的方法上处理,这就是Rest的魅力,没必要为每种操作定义不同URL(以前只有Post和Get,是做不到的)

2.同样的url不同的参数需要使用时可以用param,@GetMapping(value = "/api", params = {"operation", "sChallenge", "sResponse"}),param不同也可以使用同样的url;

2.基于类级别的根URL需唯一,两个类映射到同样的URL是不允许的,SprintBoot启动时就会报错。

16.Get、Put、Post、Delete的区别?

get查询,put更新,post新增,delete删除;

put是幂等操作,post不是;

17.url通配符有哪些?

我们还可以通过通配符对URL映射进行配置,通配符有“?”和“*”两个字符。其中“?”表示1个字符,“*”表示匹配多个字符,“**”表示匹配0个或多个路径。

例如:

“/helloworld/index?”可以匹配“/helloworld/indexA”、“/helloworld/indexB”,但不能匹配“/helloworld/index”也不能匹配“/helloworld/indexAA”;

“/helloworld/index*”可以匹配“/helloworld/index”、“/helloworld/indexA”、“/helloworld/indexAA”但不能匹配“/helloworld/index/A”;

“/helloworld/index/*”可以匹配“/helloworld/index/”、“/helloworld/index/A”、“/helloworld/index/AA”、“/helloworld/index/AB”但不能匹配    “/helloworld/index”、“/helloworld/index/A/B”;

“/helloworld/index/**”可以匹配“/helloworld/index/”下的多有子路径,比如:“/helloworld/index/A/B/C/D”;

如果现在有“/helloworld/index”和“/helloworld/*”,如果请求地址为“/helloworld/index”那么将如何匹配?Spring MVC会按照最长匹配优先原则(即和映射配置中哪个匹配的最多)来匹配,所以会匹配“/helloworld/index”

 参考

1.JavaWeb中MVC模型的演变_web mvc的演进_午-夜的博客-优快云博客

2.Java面试系列之SpringMvc请求响应_01_哔哩哔哩_bilibili

3.https://www.cnblogs.com/jiangtao1218/p/10204861.html

4.https://www.cnblogs.com/it-mh/articles/10406475.html

5.Spring&SpringBoot常用注解总结 | JavaGuide(Java面试+学习指南)

6.SpringMVC 常见面试题整理 - 知乎

7.@RestController vs @Controller

8.过滤器与拦截器区别、使用场景笔记整理 - 知乎

9.拦截器与过滤器详解,使用方式与注意事项,使用场景以及区别与联系_过滤器和拦截器的区别和使用场景_reresrse的博客-优快云博客

10.SpringBoot中使用过滤器_Lyzxii的博客-优快云博客

11.【SpringBoot】URL路径映射规则_weixin_33911824的博客-优快云博客

12. 使用RequestMapping处理同一url不同参数请求_requestmapping url参数_biuaxia的博客-优快云博客

13.总结get、put、post、delete的区别和用法_get post put_云庄clouder的博客-优快云博客

14.url通配符_JKxiaoxing的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值