Spring MVC学习笔记
Spring MVC学习笔记
springmvc是servlet的升级,在servlet的基础上加入一些功能,让web开发方便
springmvc能够创建对象,放入到springmvc容器中
使用@Controller注解创建的是一个普通类的对象,不是servlet对象,springmvc赋予了控制器对象一些额外的功能
web开发的底层就是servlet,springmvc中有一个对象是servlet:DispatherServlet(中央调度器)也叫前端控制器,font controller
index.jsp——DispatherServlet——转发,分配给——Controllet对象(@Controller创建的对象)
第一个springmvc项目
需求:用户在页面发起一个请求,请求交给springmvc的控制器对象,并显示请求的处理结果
实现步骤:
新建web maven
加入依赖 spring-webmvc依赖 ,jsp依赖,servlet依赖
重点:
在web.xml中注册springmvc的核心对象DispacherServlet
DispacherServlet是一个servlet,负责接收用户提交的请求,调用其它的控制对象,并把请求的处理结果显示给用户 ,方法返回值 void Object String ModelAndView
创建一个发起请求的index.jsp
创建控制器类
在类上面加上注解@Controller注解,创建对象,并加入到springmvc容器中
在类中的方法上面加入@RequestMapping注解,请求映射
创建显示结果的jsp
创建springmvc的配置文件,springmvc.xml
声明组件扫描器,指定@Controller注解所在的包名
声明视图解析器,帮助处理视图的
springmvc执行简单源码过程分析
tomcat启动时,创建容器的过程
通过load-on-start标签指定的1,在启动tomcat时创建DispacherServlet对象
DispacherServlet的父类是继承HttpServlet,是一个servlet,在被创建时,会执行init()方法
在init()方法中,创建容器,读取配置文件
1
2
3
4//创建容器,读取配置文件
WebApplicationContext ctx=new ClassPathXmlApplicationContext("springmvc.xml")
//把容器对象放入到servletContext中
getServletContext().setAttribute(key,value)上面创建容器的作用:创建@Controller注解所在类的对象,进而创建Controller对象,把对象放到springmvc容器中
请求处理的过程
- 执行servlet的service方法调用doDispach方法调用Controller对象中对应的方法
接收请求的参数
- HttpServletRequest
- HttpServletResponse
- HttpSession
- 用户提交的数据
- 逐个接收
- 对象接收
处理器方法的返回值
- ModelAndView——既有数据,又有视图,对视图进行forward
- String——表示视图,可以是逻辑名称,也可以是完整视图路径
- void——不能表示数据,也不能表示视图,在处理Ajax时,可以使用void返回值,通过HttpServletResponse输出数据,响应AJax请求
- Object——表示数据,和视图无关,可以使用对象表示的数据,响应ajax请求
用Object返回值做JAjax,主要使用json的数据格式,实现步骤:
加入处理json的依赖,springmvc默认使用jackson
在springmvc配置文件中加入
<mvc:annotation-driven>
注解驱动1
2相当于做了
json=om.writerValueAsString(student);在处理器方法的上面加上@ResponseBody注解
1
2
3相当于做了
response.setContentType("application/json;charset=utf-8");
response.getWriter.write(json);<mvc:annotation-driven>
注解驱动原理完成java对象到json、xml、tetx、二进制等数据格式的转换
HttpMessageConverter接口:消息转换器,这个接口有很多实现类,完成java对象到json、xml、tetx、二进制等数据格式的转换
@ResponseBody注解:把处理器方法返回对象转换为json后,通过HttpServletResponse输出给浏览器
区分返回值String是视图还是数据,看有没有@ResponseBody注解,有的话返回的是数据,没有是视图
1 |
|
tomcat本身能处理静态资源的访问,例如图片、HTML、js等
tomcat的web.xml文件中有一个名为default的servlet,在服务器启动时创建
作用:1.处理静态资源
2.未映射到其它servlet的请求
url-parrern可以使用两种值
1.扩展名方式:**.xx,例如* *.do
2.使用斜杠 “/”
当项目中使用 / ,它会替代tomcat中的default这个servlet的mapping
导致所有的静态资源都给DispacherServlet处理,默认情况下 DispacherServlet是没有处理静态 资源的控制器对象的,所以访问静态资源是404
动态资源可以访问,因为我们程序中定义了对应的控制器对象
url-pattern 使用 / 处理静态资源的方式:
第一种
在springmvc配置文件中加入 <mvc:default-servlet-handler>
原理是:加入这个标签后,框架会创建控制器对象DefaultServletHttpRequestHandler,类似于我们自己创建的控制器对象,这个对象把接收的请求转发给tomcat的default这个servlet
第二种
在springmvc配置文件中加入 <mvc:resources mapping="" location="">
加入后框架会创建ResourceHttpRequestHandler这个处理器对象,用这个对象处理静态资源,不依赖tomcat服务器
mapping:访问静态资源的url地址,使用通配符 **
location:静态资源在你的项目中的目录位置
直接把静态资源放在statics目录下
1 |
|
路径+资源:localhost:8080/chapter06/user/index.html
路径:localhost:8080/chapter06/user/
资源:index.html
访问路径不加 / 时,
1 |
|
访问路径加上 / 时,使用EL表达式 ${pageContext.request.contextPath}
1 |
|
当在index.jsp点击后,第一次点击跳转正常localhost:8080/chapter06/user/index.html
,第二次报404错误localhost:8080/chapter06/user/user/index.html
解决方法:
- 在跳转地址上面加上EL表达式
${pageContext.request.contextPath}
,但是如果有多个跳转地址,就需要加多个 - 使用html的base标签,基地址,
<base href="http://localhost:8080/chapter06/">
如果每个页面都要自己写base标签中的值得话,很麻烦
1 |
|
SSM整合
SSM也叫SSI(IBatis),第一个容器是Spring容器,负责管理service、dao、工具类对象的,第二个容器是SpringMVC容器,负责管理控制器对象、web开发相关对象的,我们要做的就是把使用的对象交给合适容器创建,管理。
spring容器和springmvc容器是由关系的,关系已经确定好了,springmvc容器是spring容器的子容器,类似于java中的继承,子可以访问父的内容
实现步骤:
数据库表:student(id 自增型 ,name,age)
新建maven web项目
加入依赖,spring,springmvc,mybatis三个框架的依赖,jackson依赖,mysql驱动,druid连接池,jsp,servlet依赖
写web.xml
注册DispacherServlet,目的:1,创建springmvc容器,才能创建控制器对象
2,创建的是servlet,才能接收用户请求
注册spring的监听器:ContextLoderListener,目的:创建spring的容器对象,才能创建service,dao等对象
注册字符集过滤器,解决post请求乱码的问题
创建包,controller, service, dao ,entity
写springmvc,spring,mybatis配置文件,数据库属性配置文件
写代码,dao接口,mapper文件,service和实现类,controller,实体类
写jsp页面
SpringMVC核心技术
forward:表示转发,实现request.getRequestDispacher().forward()
redirect:表示重定向,实现reponse.sendRedirect()
请求转发是可以访问WEB-INF中的资源的,而重定向是不可以的
显式转发,扩展了默认的转发操作,不受视图解析器的控制
语法:setViewName(“forward:/WEB-INF/view/hello.jsp”);
作用和setViewName(“hello”);是一样的,如果view下面没有hello.jsp的话,用视图器这个访问不能访问到WEB-INF下面的内容,这个时候用forward就方便