初识SpringMvc
什么是MVC
-
MVC是用来分层解耦的。
-
Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
-
一个请求进来,会先经过展示层(控制器 和 视图 servlet) ---- 业务逻辑层(spring) ---- 数据访问层(jdbc mybatis) ---- 数据库
-
一个请求进行,会先经过控制器(Controller SpringMVC) ---- 模型(Model spring [实体Bean 业务Bean]) ------数据访问层(Mybatis) ---数据库
SpringMVC基础概念
-
SpringMVC是基于spring的,是spring的一个模块,做web开发使用。使用spring核心技术做web开发,springMVC内部使用的是 MVC架构。
-
SpringMVC也是一个容器,用来管理对象,使用的是IOC技术,SpringMVC管理界面层中的控制器对象。
-
SpringMVC处理请求笼统过程描述: 用户发起请求 --- SpringMVC --- 调用Spring托管的dao service----Mybatis --- 数据库
-
SpringMVC中的核心Servlet 叫做: disPatcherServlet,负责接收请求,响应请求处理结果,它的父类是HttpServlet。
-
disPatchServlet也叫做前端控制器(front controller)。
-
SpringMVC管理控制器对象,原来在没有springMVC之前,会将Servlet作为控制器对象使用。现在通过SpringMVC创建一种叫做控制器的对象,代替Servlet
行使控制器的角色和功能。 -
SpringMVC是基于Spring的,是Spring中的一个模块,也叫做SpringWeb MVC,使用Spring的核心技术,做WEB开发。
-
SpringMVC 也是一个容器,使用IOC技术管理对象,SpringMVC属于界面层,用于管理界面层的控制器对象,底层是Servlet,接收请求,处理请求,返回请求结果。
SpringMVC使用方式
- SpringMVC主要使用注解的方式创建控制器对象,处理请求。
SpringMVC中的核心Servlet-----中央调度器(dispatcherServlet)
-
dispatcherServlet是框架中的一个Servlet对象,他负责去接收请求,响应处理结果。它的父类是HttpServlet。
-
dispatcherServlet也叫做前端控制器(front controller)。
-
SpringMVC可以管理控制器对象,原来没有SpringMVC的时候使用的是Servlet来管理控制器对象,现在通过SpringMVC容器创建一种叫做控制器对象,代替Servlet行使
控制器的功能。 -
新建SpringMVC的步骤
-
新建WEB应用
-
加入所需依赖
-
声明SpringMVC核心对象dispatcherServlet(web.xml)
dispatcherServlet的作用:(1) 在Servlet的init()方法中,创建SpringMVC中的容器对象,创建所有java对象,也就是Controller对象。
(2) 作为Servlet接收请求。dispatcherServlet org.springframework.web.servlet.dispatcherServlet contextConfigLocation classpath:dispatcher-Servlet.xml 1 dispatcherServlet *.do
-
-
SpringMVC 请求过程
用户发起请求some.do --- TomCat接收了请求(Tomcat根据Web.xml文件中的
*.do)
Tomcat发现扩展名是.do结尾的,所以将some.do请求交给了当前dispatcherServlet对象处理(中央调度器),中央控制器中收集了所有请求。并将这些请求存储在一个Map中
例如:Map(类名key,请求名Value)。dispatcherServlet对象(中央调度器)根据springMVC的配置文件,解析注解,将这个请求分配给了Controller类(后端控制器)根据注解@RequestMapping注解,
将请求分配给Controller类下的方法,doSome()方法,doSome()方法处理请求,返回ModelAndView对象给前端页面。首先,SpringMVC框架在启动的时候会遍历spring容器中的所有bean,对标注了@Controller或@RequestMapping注解的类中方法进行遍历,
将类和方法上的@RequestMapping注解值进行合并,(@RequestMapping注解的相关参数值 如value、method等等)封装一个RequestMappingInfo对象中,
然后将这个Controller实例、方法及方法参数信息(类型、注解等等)封装到一个HandlerMethod对象中。
然后以RequestMappingInfo对象为key,HandlerMethod对象为value封装到一个以Map为结构的handlerMethods对象中。
接着,将@RequestMapping注解中的value(即请求路径)值取出,即url,然后以url为key,以RequestMappingInfo为value,存到一个以Map为结构的urlMap对象属性中。客户端发起请求的时候,根据请求的URL到urlMap中查找,找到RequestMappingInfo,然后根据RequestMappingInfo到handlerMethods中查找,找到对应的HandlerMethod,
接着将HandlerMethod封装到HandlerExecutionChain对象中;接着遍历容器中所有HandlerAdapter实现类,找到支持这次请求的HandlerAdapter,
如RequestMappingHandlerAdapter,然后执行SpringMVC拦截器的前置方法(preHandle方法),然后对请求参数解析及转换,
然后(使用反射)调用具体Controller的对应方法返回一个ModelAndView对象,执行拦截器的后置方法(postHandle方法),然后对返回的结果进行处理,最后执行afterCompletion方法。
SpringMVC注解式开发
-
@RequestMapping注解
-
该注解可以放在类上使用,也可以放在类下的方法上使用。
-
在同一个Controller类中存在多个方法,那么该类下的方法上 @RequestMapping注解值,都会有一个公用的请求路径,那么就可以把/test/这个请求路径提取出来,放在类上边
@RequestMapping(value = {"/test/some.do","/test/first.do"}) @RequestMapping(value = {"/test/other.do","/test/second.do"})
-
@RequestMapping(value(),method) 有两个属性,一个Value中填写请求地址,另一个是method,填写请求方式。
例如: @RequestMapping(value = ("/test"), method = RequestMethod.GET) -
@RequestParam(value="",required=true/false) 该注解用来指定form表单请求参数的参数名。require表示是否允许为空。
-
各个配置文件说明
-
web.xml 部署描述符文件 该文件是给服务器用的,给Tomcat用的,TomCat在启动的时候,读取web.xml,根据文件中的各种声明,创建各种对象 和 通过web.xml的各种声明描述
知道 各种请求和Servlet的对应关系。 -
框架配置文件,ApplicationContext.xml、spring-servlet.xml,beans.xml,声明框架创建的项目中的各种对象,主要是创建Controller对象。
-
配置文件加载的顺序: Tomcat服务器启动,首先要读取的是 web.xml文件,根据web.xml文件中的声明,首先会创建一个dispatcherServlet对象,
在创建dispatcherServlet对象的过程中会在init()方法中进行SpringMVC容器对象的创建
contextConfigLocation
classpath:springmvc-servlet.xml
相等于 WebApplicationContext context = newClasspathXmlApplicationContext("spring-servlet.xml");
SpringMVC容器对象创建的时候读取SpringMVC配置文件 spring-servlet.xml。
如何在Controller类中接收请求参数
- 如果需要 HttpServletRequest,HttpServletResponse, HttpSession 可以在形参中直接定义,就可以使用了。
- 接收请求中的参数又分为两大类,逐个接收 和 对象接收
1.逐个接收参数(表单中的参数名 和 Controller形参名称一致的情况)
- 使用框架的时候,只要保证form表单中所提交的参数的参数名,和Controller类形参中的参数名一致,类型一致,就可以直接接收表单数据。
相当于 request.getParameter(String name);
- 当允许表单所提交数据为空的时候,Controller类的形参类型,应该为包装类型,这样允许为空,才能够提交NULL
2.逐个接收参数(表单中的参数名 和 Controller形参名称不一致的情况)
- 使用@RequestParam注解: 解决表单中的参数名 和 Controller形参参数名不一致的情况
- 该注解有两个属性 value 和 required,
value 用来表示请求中的参数名,放在形参定义的前面。
public ModelAndView getParam(@RequestParam(value = "username") String name, int age);
required 默认值是true,true表示请求中必须有此参数,不能为空,没有就报错;false表示请求中可以没有此参数,可以为空。
3. 对象接收
- 后台控制器方法的形参是java对象,使用java对象的属性接收请中的参数值。
- java对象的属性名要是形式参数名保持一致
解决乱码问题
-
request.setCharacterEncoding("utf-8"); 该方式需要在接收参数之前设置有效,设置动态文字(参数,数据库)
-
response.setContentType("text/xml;charset=GBK") 设置页面静态文字 ,作用是让浏览器用utf-8来解析返回的数据
-
response.setCharacterEncoding() 告诉servlet用utf-8转码,而不是默认的iso8859-1,是设置从request中取得的值或从数据库中取出的值
-
设置过滤器,在web.xml中,框架提供了一个过滤器. 使用框架自带过滤器。
characterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter <!--属性1. 项目所使用的的字符编码--> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <!--属性2. 强制请求对象 request,使用encoding编码方式--> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <!--属性3. 强制响应对象 response ,使用encoding编码方式 --> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param>
characterEncodingFilter /*
后台控制器的返回值类型
- 返回值类型包括: ModelAndView、Model、String、void、Object。
-
ModelAndView
- ModelAndView 包括数据和视图两部分,其中数据存放在request作用域; 视图执行forward转发操作。
-
Model
- Model 只是用来传输数据的,不能存放视图,不能进行业务寻址。
-
String
-
void
-
Object
-
返回数据Object,可以使集合、Student、User,String,这些都是数据,而Ajax请求需要的就是数据,所以后台控制器返回对象的时候一般都是响应ajax请求。
-
在ajax请求中,一般需要从服务器端返回的是json格式的数据,所以我们需要处理java对象到json字符串的转换,而且还需要将json数据输出,去响应ajax的请求。
-
框架提供了java对象到json转换,还有将json字符串输出的工作。
-
HttpMessageConverter接口 消息转换器,作用:
1) 实现将前台页面发过来的请求所携带的数据转换为java对象
2) 将后台控制器方法返回的对象转换为json,xml,text,二进制等不同格式的数据。 -
视图页面(html,jsp等)发起请求并携带数据(name=zhangsan;password=123),后端控制器接收到请求和数据,
并使用HttpMessageConverter接口将前台页面发过来的请求所携带的数据转换为java对象,给Controller使用。
Controller处理完成返回给前端页面一个对象,但是Ajax需要json字符串,此时继续使用HttpMessageConverter接口
将对象转换为json字符串,返回给前端页面。
-
-
String 类型的数据 不是视图
HttpMessageConverter接口
-
HttpMessageConverter接口下的方法(这四个方法不用程序员手动调用,框架会自动调用)
-
boolean canRead(Class<?> clazz,@Nullable MediaType mediaType);
MediaType: MediaType表示媒体类型,是指在互联网中所传输的数据格式,例如:application/json、text/html、 image/gif
作用: 检查clazz这个类能否转换成mediaType所表示的数据格式,如果能转换为mediaType那么就返回true,就会调用read()方法; 如果不能转换为mediaType那么就返回false。 -
T read(Class<? extends T>clazz,HttpInputMessage inputMessage);
作用:接收请求中携带过来的数据,将数据转换为clazz所表示的对象。 -
boolean canWrite(Class<?> clazz,@Nullable MediaType mediaType);
作用: 检查clazz这个类型能否转为 mediaType所表示的数据格式。如果能就返回true,就会调用write()方法。 -
void write(T t,@Nullable MediaType mediaType, HttpOutputMessage);
作用: 把T对象,按照mediaType所说明的格式,将Object转换为mediaType所对应的格式(json,xml...)
-
HttpMessageConverter接口的实现类
-
该接口下有很多实现类,主要掌握两个实现类就可以。
-
MappingJackson2HttpMessageConverter
作用: 使用Jackson工具库中的ObjectMapper,把java对象转换成json的数据格式 -
StringHttpMessageConverter
作用: 把字符串类型的数据,进行格式的转换和编码。
-
-
怎么使用实现类呢?
-
默认情况下,SpringMVC使用了HttpMessageConverter接口下的四个实现类,包括了StringHttpMessageConverter,
但是不包括MappingJackson2HttpMessageConverter,所以需要在SpringMVC的配置文件中,加入一个注解驱动的标签,mvc:annotation-driven。
加入了这个注解驱动标签后,SpringMVC项目启动后会创建HttpMessageConverter接口下的八个实现类对象,包括了MappingJackson2HttpMessageConverter实现类。相等于:
//把对象转换为json格式并赋值
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsstring(user);
System.out.println("服务器端的对象转为的json字符串"+json);
注解 @RequestBody注解 自动输出
-
作用: @RequestBody注解 把HttpMessageConverter接口转换后的数据通过HttpServletResponse对象输出给浏览器。
相等于:
//输出Json到前端页面响应ajax
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.println(json);
out.flush();
out.close();
后台控制器返回对象(Object) 转换为json的步骤
-
在pom.xml中加入jackson的依赖,SpringMVC框架,默认处理json字符串就是使用的jackson。
-
在SpringMVC的配置文件中,加入注解驱动的标签mvc:annotation-driven/
-
在控制器方法上加 @RequestBody注解,表示将转换后的Object数据,响应给浏览器。
-
框架是怎么做到自动将返回值类型(Object)转换为各种字符格式的呢?
1.框架会根据控制器方法的返回值类型(ModelAndView、String、Void、Object),找到HttpMessageConverter接口,然后在该接口中找到8中实现类中的对应的实现类。
2.找到实现类MappingJackson2HttpMessageConverter以后,执行该类的Write()方法,将返回的user对象转换为json格式的数据。
3.框架提供@ResponseBody注解,通过HttpServletResponse对象,将第二步中转换好的json数据,输出给了浏览器。
后台控制器返回String类型数据的过程
-
框架会根据控制器方法的返回值类型(ModelAndView、String、Void、Object),找到HttpMessageConverter接口,然后在该接口中找到8中实现类中的对应的实现类。
-
处理String类型数据的实现类是 StringHttpMessageConverter类。StringHttpMessageConverter使用的编码方式是 text/plain;charset=ISO-8859-1。
-
该类返回的不是json字符串,而是text文本。
中央调度器(front controller) 中的
-
*.do .do表示所有以.do结尾的请求,都交给当前dispatcherServlet来处理分发。 -
/ / 表示所有请求都交给当前dispatcherServlet来处理分发包括静态资源,但是当前dispatcherServlet处理不了静态资源。
如何解决静态资源不能处理的情况呢?
-
方式一
-
在SpringMVC配置文件中创建DefaultServletHttpRequestHandler对象,它会像一个检查员一样,对dispatcherServlet的请求URL进行筛查
如果发现是静态资源请求,就将该请求转由Tomcat自带的默认Servlet,DefaultServlet处理。 -
创建DefaultServletHttpRequestHandler对象的方式?
-
-
注解方式: mvc:default-servlet-handler/
但是该注解和@RequestMapping注解有冲突,会导致动态资源(some.do)无法访问,所以要使用mvc:default-servlet-handler/,必须先声明 mvc:annotation-driven/。
-
-
-
方式二
-
在SpringMVC配置文件中创建ResourceHttpRequestHandler控制器对象,它会去处理静态资源的访问,这种方式不依赖Tomcat服务器。是框架来处理的。
-
如何创建ResourceHttpRequestHandler对象?
-
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。