SpringMVC(王)

SpringMVC(王)

SpringMVC:是基于spring的框架,实际上就是spring的一个模块,专门是做web开发的,是servlet的一个升级

web开发底层是servlet,框架是在servlet基础上加入一些功能,让你做web开发更加方便

SpringMVC就是一个Spring。Spring是容器,ioc能够管理对象,使用,@Componet,@Repository,@Service,@Controller

SpringMVC能够创建对象,放入到容器中(SpringMVC容器),springmvc容器中放入的是控制器对象(controller)

我们要做的是:使用@Controller创建控制器对象,把对象放入到springmvc容器当中,把创建的对象作为控制器使用,这个控制器对象能够接收用户的请求,显示处理结果,就当作是一个servlet使用

使用@Controller注解创建的是一个普通类的对象,不是servlet,springmvc赋予了控制器对象一些额外的功能

web开发底层是servlet,springmvc中有一个对象是servlet:DispatcherServlet。DispatcherServlet:负责接收用户的所有请求,用户把请求给了DispatherServlet,之后DispatcherServlet把请求转发给了我们的Controller对象,最后是Controller对象处理请求

index.jsp------DispatcherServlet(servlet)-------转发,分配给Controller对象(@Controller注解创建的对象)

需求:用户在页面发起了一个请求,请求交给springmvc的控制器对象,并显示请求的处理结果(把结果页面显示一个欢迎语句)

实现步骤:

1.新建web maven工程

2.加入依赖

​ spring-mvc依赖,间接把spring的依赖都加入到项目

​ jsp,servlet依赖

3.重点:在web.xml中注册springmvc框架的核心对象DispatcherServlet

​ DispatcherServlet叫做中央调度器,是一个servlet,它的父类继承HttpServlet

​ DispatcherServlet也叫做前端控制器(front controller)

​ DispatcherServlet负责接收用户的请求,调用其它的控制器对象,并把请求的处理结果显示给用户

4.创建一个发起请求的页面,index.jsp

5.创建控制器类

​ 在类的上面加入@Controller注解,创建对象,并放入到springmvc容器中

​ 在类的方法上面加入@RequestMapping注解

6.创建一个作为结果的jsp,显示请求的处理结果

7.创建springmvc的配置文件(和spring的配置文件一样)

​ 声明组件扫描,指定@Controller注解所在的包名

​ 声明视图解析器,帮助处理视图的


springmvc请求的处理流程

  1. 用户发起some.do请求----
  2. tomcat(web.xml—url-pattern直到*.do的请求是给DispatcherServlet)-----
  3. DispatcherServlet(根据springmvc.xml配置知道some.do—doSome())------
  4. DispatcherServlet把some.do转发给MyController.doSome()方法------
  5. 框架执行doSome()把得到的ModelAndView进行处理,转发到show.jsp

springmvc执行过程源代码分析

  1. tomcat启动,创建容器的过程

    通过load-on-start标签指定的1,创建DispatcherServlet对象,父类继承HttpServlet,在被创建时,会执行init()方法,在init()方法中执行

    //创建容器,读取配置文件
    WebApplicationContext ac = new ClassPathXmlApplicationContext(springmvc.xml);
    //把容器对象放入到ServletContext中
    getServletContext.setAttribute(key,ac);
    

    上面创建容器作用:创建@Controller注解所在的类的对象,创建MyController对象,这个对象放入到springmvc的容器中,容器是map,类似于map.put(“myController”,MyController对象)

  2. 请求的处理过程

    • 执行servlet的service()方法
    • 执行doService()方法
    • 执行doDispatch()方法,这个方法调用MyController的doSome()方法

控制器方法的返回值

使用@Controller注解的处理器的处理器方法,其返回值常用的有四种类型

  1. ModelAndView
  2. String
  3. 无返回值 void
  4. 返回自定义类型对象

根据不同的情况,使用不同的返回值

返回值 ModelAndView

如果处理器方法处理后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回ModelAndView比较好,当然,若要返回ModelAndView,则处理器方法中需要定义ModelAndView对象,如果只需要数据或者只进行页面跳转就不推荐使用ModelAndView

返回值 String

如果只需要页面之间的跳转,可以使用String

返回void

若处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回void,例如:对于AJAX的异步请求的响应,通过HttpServletResponse输出数据,响应ajax请求,ajax请求服务器端返回的就是数据,和视图无关

返回对象Object

处理器方法可以返回Object对象,这个Object可以是Integer,String,自定义对象,Map,List等,但返回的对象不是作为逻辑视图出现的,而是作为直接在页面中显示的数据出现的

返回对象,需要使用ResponseBody注解,将转换后的JSON的数据放入到响应体中

现在做ajax,主要使用json的数据格式

实现步骤:

  1. 加入处理json的工具库的依赖,springmvc默认使用的是jackson
  2. 在springmvc配置文件中加入《mvc:annotation-driven》标签,注解驱动,作用是把java对象转换为json数据
  3. 在处理器方法的上面加入@ResponseBody注解,作用是将:json数据放入到响应中

springmvc处理器方法返回Object,可以转为json输出到浏览器,响应ajax的内部原理

  1. 《mvc:annotation-driven>注解驱动

    注解驱动实现的功能是,完成java对象到json,xml,text,二进制等数据格式的转换

    HttpMessageConverter:接口,消息转换器

    功能:定义了java转为json,xml等数据格式的方法,这个接口有很多的实现类。这些实现类完成java对象到json,java对象到xml,java对象到二进制数据的转换

    HttpMessageConverter接口中的下面两个方法是控制器类把结果输出到浏览器时使用的
    boolean canWrite(Class<?> var1, @Nullable MediaType var2);
    void write(T var1, @Nullable MediaType var2, HttpOutputMessage var3)
    

在jsp,html中使用的地址,都是在前端页面中的地址,都是相对地址

相对地址不能独立使用,必须有一个参考地址,通过参考地址,相对地址本身才能指定资源

参考地址

在你的页面中,访问地址不加"/"

访问的是:http://localhost:8080/cho6-path/index.jsp

路径:http://localhosdt:8080/ch06-path/

资源:index.jsp

在index.jsp发起 user/some.do 请求,访问地址变为 http://localhost:8080/ch06-path/user/some.do

当你的地址没有斜杠开头,例如: user/some.do,当你点击连接时,访问地址是当前页面地址,再加上连接本身的地址

http://localhost:8080/ch06-path/ + user/some.do

在你的页面中,访问地址加上"/"

访问的是:http://localhost:8080/cho6-path/index.jsp

路径:http://localhosdt:8080/ch06-path/

资源:index.jsp

点击 /user/some.do ,访问地址变为 http://localhost:8080/user/some.do,缺少了网站名 cho6-path

加上 / 访问的是 ip+端口号

解决办法,在 /user/some.do 前面加上 /cho6-path/user/some.do,就可以了,但是这样不灵活,不推荐

还可以使用el表达式

<a href="${pageContext.request.contextPath}/user/some.do">发起user/some.do的请求</a>

在不加上 / 的时候,也会出现问题

还有一个问题,如果在index.jsp页面中点击user/some.do后,页面的跳转是跳转回index.jdp,这个时候再次点击user/some.do,会出现问题

第一次点击user/some.do跳转后的地址

http://localhost:8080/ch06-path/user/some.do

再次点击user/some.do之后跳转的地址

http://localhost:8080/ch06-path/user/user/some.do

这是因为,第一次跳转后,参考地址中的路径已经改变为http://localhost:8080/ch06-path/user/,这个时候再次点击就会加上user/some.do,变成http://localhost:8080/ch06-path/user/user/some.do

有两种解决方法

第一种,加上/,使用el表达式

第二种,加入一个base标签,是html语言当中的标签,表示当前页面中访问地址的基地址,你的页面当中所有没有”/“开头的地址,都是以base标签中的地址为参考地址

<html>
    <head>
        <title>title</title>
        <base href="http://localhost:8080/ch06-path/" />
    </head>
    <body>
        <a href="user/some.do">发起user/some.do的请求</a>
    </body>
</html>

这样无论点多少次都不会有问题,但是这样不够灵活,话可以再次进行修改

<% 
	String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPost+request.getContextPath()+"/";   
%>
<html>
    <head>
        <title>title</title>
        <base href="<%=basePath%>" />
    </head>
    <body>
        <a href="user/some.do">发起user/some.do的请求</a>
    </body>
</html>

这样就能动态的获取地址

SSM整合

springmvc中的请求转发和重定向

当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发和重定向,而根据索要跳转的资源类型,又可以分为两类:跳转到页面和跳转到其它处理器

注意,对于请求转发的页面,可以是WEB-INF中页面,而重定向的页面,是不能为WEB-INF中的页面的,因为重定向相当于用户再次发出一次请求,而用户是不能直接访问WEB-INF中的资源的

springmvc框架把原来的Servlet中的请求转发和重定向操作进行了封装,现在可以使用简单的方式实现转发和重定向

forward:表示转发,实现 request.getRequestDispatcher(“xx.jsp”).forward();

redirect:表示重定向,实现response.sendRedirect(“xxx.jsp”)

异常处理:

springmvc框架采用的是统一,全局的异常处理

把controller中的所有异常处理都集中到一个地方,采用的是aop的思想,把业务逻辑和异常代码分开,解耦合

使用到两个注解

@ExceptionHandler

@ControllerAdvice

异常的处理步骤

1.新建maven web项目

2.加入依赖

3.新建一个自定义异常类,MyUserException,在定义它的子类NameException,AgeException

4.在Controller中抛出NameException,AgeException

5.创建一个普通类,作为全局异常处理类

​ 1)在类的上面加入@ControllerAdvice

​ 2)在类中定义方法,方法的上面加入@ExceptionHandler

6.创建处理异常的视图页面

7.创建springmvc的配置文件、

​ 1)组件扫描器,扫描@Controller注解

​ 2)组件扫描器,扫描@ControllerAdvice所在的包名

​ 3)声明注解驱动

拦截器

springmvc中的interceptor拦截器是非常重要和相当有用的,它的主要作用就是拦截指定的用户请求,并进行相应的预处理和后出处理,其拦截的时间点在“处理器映射器根据用户提交的请求映射出了索要执行的处理器类,并且也找到了要执行该处理类的处理器适配器,在处理器适配器执行处理器之前。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了要给处理器执行链,并返回给了中央调度器

拦截器是springmvc中的一种,需要实现HandlerInterceptor接口

拦截器和过滤器类似,功能方向侧重点不同,过滤器是用来过滤请求参数,设置编码字符集等工作

拦截器是拦截用户的请求,对请求做判断处理的

拦截器是全局的,可以对多个Controller做拦截,项目中可以没有或者多个拦截器,他们在一起拦截用户的请求,拦截器常用在:用户登录处理,权限检查,记录日志

使用步骤

1.定义类实现HandlerInterceptor接口

2.在springmvc配置文件中,声明拦截器,让框架知道拦截器的存在

拦截器的执行时间

1.在请求处理之前,也就是controllerr类中的方法执行之前先被拦截

2.在控制器方法执行之后也会执行拦截器

3.在请求处理完成后也会执行拦截器

拦截器:看做是多个Controller中公用的功能,集中到拦截器统一处理,使用的aop的思想


多个拦截器

第一个拦截器preHandle=true,第二个拦截器preHandle=true

11111111-拦截器的MyInterceptor的preHandle()
2222222-拦截器的MyInterceptor的preHandle()
执行MyController的doSome()方法
2222222-拦截器的MyInterceptor的postHandle()
11111111-拦截器的MyInterceptor的postHandle()
2222222-拦截器的MyInterceptor的afterHandle()
11111111-拦截器的MyInterceptor的afterHandle()

以控制器方法为界限,有一种先进后出的感觉

拦截器执行链

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2SW5CZVz-1635916101636)(D:\知识点截图\java基础知识\拦截器执行链.png)]

第一个拦截器preHandle=true,第二个拦截器preHandle=false

11111111-拦截器的MyInterceptor的preHandle()
2222222-拦截器的MyInterceptor的preHandle()
11111111-拦截器的MyInterceptor的afterHandle()

拦截器的preHandle=true,则afterHandle()方法一定会执行

第一个拦截器preHandle=false,第二个拦截器preHandle=false/true

11111111-拦截器的MyInterceptor的preHandle()

拦截器和过滤器的区别

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

springmvc的执行流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnvzUSIl-1635916101639)(D:\知识点截图\java基础知识\springmvc的执行流程.png)]

springmvc内部请求的处理流程:也就是springmvc接收请求,到处理完成的过程

  1. 用户发起请求some.do

  2. DispatcherServlet(中央调度器)接收请求some.do,把请求转交给处理器映射器

    处理器映射器:Springmvc框架中的一种对象,框架把实现了HandlerMapping接口的类都叫做映射器(多个) ,我应该使用的实现类是RequestMappingHandlerMapping

    处理器映射器作用:根据请求,从springmvc容器对象当中获取处理器对象(controller对象),框架会把找到的处理器对象放到一个叫做处理器执行链(HandlerExecutionChain)的类保存

    HandlerExecutionChain:类中保存着,1.处理器对象(MyController);2.项目中的所有的拦截器

  3. DispatcherServlet把2中的HandlerExecutionChain中的处理器对象交给了处理器适配器对象(多个)

    处理器适配器:springmvc框架中的对象,需要实现HandlerAdapter接口

    处理器适配器的作用:执行处理器方法(调用MyControler中的doSome()方法,得到返回值ModelAndView)

  4. DispatchperServlet把3中获取的ModelAndView交给了视图解析器对象

    视图解析器:springmvc中的随想,需要实现ViewResoler接口(可以有多个)

    视图解析器作用:组成视图完成路径,使用前缀,后缀。并创建View对象,View是要给接口,表示视图的,在框架中jsp,html不是String表示,而是使用View和它的实现类表示视图

    InternalResourceView:视图类,表示Jsp文件,视图解析器会创建InternalResourceView类对象,这个对象里面,有一个属性URL=/WEB-INF/view/show.jsp

  5. DispatcherServlet把4步骤中创建的View对象获取到,调用View类自己的方法,把Model数据放入到request作用域,执行对象视图的forward,请求结束

et把3中获取的ModelAndView交给了视图解析器对象

视图解析器:springmvc中的随想,需要实现ViewResoler接口(可以有多个)

视图解析器作用:组成视图完成路径,使用前缀,后缀。并创建View对象,View是要给接口,表示视图的,在框架中jsp,html不是String表示,而是使用View和它的实现类表示视图

InternalResourceView:视图类,表示Jsp文件,视图解析器会创建InternalResourceView类对象,这个对象里面,有一个属性URL=/WEB-INF/view/show.jsp

  1. DispatcherServlet把4步骤中创建的View对象获取到,调用View类自己的方法,把Model数据放入到request作用域,执行对象视图的forward,请求结束
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值