一、SpringMVC简介
1、Servlet的缺点
1)使用Servlet进行开发,通常情况下,一个Servlet类处理一个请求,如果一个项目有成百上千个请求需要处理,就需要创建成百上千个Servlet来处理这些请求,Servlet类的个数暴增。
2)在Servlet2.5及2.5之前的版本中,每一个Servlet需要在web.xml文件中至少8行以上的配置,在团队开发时,配置信息太多,也容易出现问题
3)Servlet中通过request获取请求参数,无论传过来的是什么值,接收时一律按照字符串进行接收,如果这个值是数值或者日期类型的值,后期还需要强制转换。
request.getParameter(String paramName) String
request.getParameterValues(String paramName) String[]
4)Servlet需要依赖于服务器运行,不能进行单元测试。
。。。
2、SpringMVC介绍
SpringMVC是Spring框架中的一个模块,是针对表现层提出来相应的解决方案
SpringMVC是基于MVC设计模式的表现层框架。它没有完全替换Servlet,底层也是通过Servlet来实现。
DispatcherServlet:前端控制器,用于接收分发请求给各个组件,由各个组件对请求进行处理,最后将处理的结果响应给浏览器。
DispatcherServlet需要在web.xml文件中进行配置。
3、SpringMVC执行过程
一个请求匹配前端控制器 DispatcherServlet 的请求映射路径(在 web.xml中指定), WEB 容器将该请求转交给 DispatcherServlet 处理
DispatcherServlet 接收到请求后, 将根据 请求信息 交给 处理器映射器 (HandlerMapping)
HandlerMapping 根据用户的url请求 查找匹配该url的 Handler,并返回一个执行链
DispatcherServlet 再请求 处理器适配器(HandlerAdapter) 调用相应的 Handler 进行处理并返回 ModelAndView 给 DispatcherServlet
DispatcherServlet 将 ModelAndView 请求 ViewReslover(视图解析器)解析,返回具体 View
DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)
DispatcherServlet 将页面响应给用户
springmvc优点
1.封装代码,维护成本低,耦合性低
在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。
2.有利于开发中的分工,提高开发效率
在MVC模式中,由于按层把系统分开,那么就能更好的实现开发中的分工。网页设计人员可以进行开发视图层中的JSP,对业务熟悉的开发人员可开发业务层,而其它开发人员可开发控制层。
3.组件重用,有利于代码复用,重用性高
分层后更有利于组件的重用。如控制层可独立成一个能用的组件,视图层也可做成通用的操作界面。
缺点
1.没有明确的定义
2.不适合小型,中等规模的应用程序
二、SpringMVC的入门案例
√ 1、创建工程、导入jar包、创建配置文件
1)CGB-SPRINGMVC-01(Maven的Web工程)
2)导入springmvc的jar包(包括spring的jar包)
以及Servlet、jsp的jar包
3)提供src/main/resources/springmvc-config.xml
2、到web.xml文件中配置前端控制器(DispatcherServlet)
1)配置前端控制器servlet-class、url-pattern
配置前端控制器拦截除JSP以外的所有请求。
2)配置springmvc核心配置文件的位置
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
3、创建 /WEB-INF/pages/home.jsp文件
/WEB-INF/pages/test.jsp文件
4、创建一个Controller(HelloController)
com.tedu.controller.HelloController
5、配置springmvc的核心配置文件
6、编写HelloController类,完成需求,并运行测试!
---------------------------------------
@Controller
@RequestMapping("/HelloController")
public class HelloController {
@RequestMapping("/hello")
public String testHello() {
return "xxx";
}
}
localhost:8080/CGB-SPRINGMVC-01/hw/hello
---------------------------------------
@Controller
public class HelloController {
@RequestMapping("/hello")
public String testHello() {
return "xxx";
}
}
localhost:8080/CGB-SPRINGMVC-01/hello
---------------------------------------
三、SpringMVC参数绑定
===============================================
1、简单类型参数绑定---------------------------------
1.1.需求:
浏览器请求:localhost:8080/CGB-SPRINGMVC-01/testParam1?name=张飞&age=20&addr=北京
获取请求中的name、age、addr参数的值
/* 1.简单类型参数绑定
* 浏览器请求: /testParam1?name=张飞&age=20&addr=北京
* 获取请求中携带的name、age、addr参数的值
*/
@RequestMapping("/testParam1")
public String testParam1( String name,Integer age,String addr ) {
System.out.println( "name="+name );
System.out.println( "age="+age );
System.out.println( "addr="+addr );
return "home";
}
总结:这种接收请求参数的方式要求:(1)方法上形参的类型要和请求参数值的类型保持一致;
(2)方法上形参的名字要和请求参数名保持一致;
2、包装类型参数绑定---------------------------------
浏览器请求:localhost:8080/CGB-SPRINGMVC-01/testParam2?name=刘备&age=22&addr=河北
获取请求中的name、age、addr参数的值
声明一个User类,在User类中声明name、age、addr属性,并提供对应的set和get方法
/* 3.包装类型参数绑定
* 浏览器请求:/testParam2?name=刘备&age=22&addr=河北
* 获取请求中的name、age、addr参数的值
* 声明一个User类,在User类中声明name、age、addr属性,并提供对应的set和get方法
*/
@RequestMapping("/testParam2")
public String testParam2( User user ) {
System.out.println( "name="+user.getName() );
System.out.println( "age="+user.getAge() );
System.out.println( "addr="+user.getAddr() );
return "home";
}
总结:这种接收请求参数的方式要求:在包装类型中的属性名和请求参数的名字保持一致(底层是调用包装类型的setXxx方法为xxx属性赋值,而赋的值来自于请求参数中名称为xxx参数的值)
3、日期类型参数绑定---------------------------------
浏览器请求:localhost:8080/CGB-SPRINGMVC-01/testParam3?birthday=2020-2-8 15:13:41
获取请求中的date参数的值
/* 4.日期类型的参数绑定
* 浏览器请求:/testParam4?date=2020-3-3 15:36:08
* 获取请求中的date参数的值
* HTTP Status 400 – Bad Request: 请求参数类型不匹配
* 因为springmvc框架底层默认的时间格式是以斜杠(/)分隔,例如:
* /testParam3?birthday=2020/3/3 15:36:08
* 因此,解决方式一:将浏览器发送的日期格式改为斜杠分隔
* 解决方式二:将springmvc框架底层默认以斜杠分隔时间改为用横杠分隔
* 注意:改为横杠分隔后,斜杠分隔的时间在服务器端将无法接收
*/
@RequestMapping("/testParam4")
public String testParam4( Date date ) {
System.out.println( "date="+date );
return "home";
}
/* 自定义日期转换格式:将springmvc框架底层默认以斜杠分隔时间改为用横杠分隔 */
@InitBinder
public void InitBinder (ServletRequestDataBinder binder){
binder.registerCustomEditor(java.util.Date.class,
new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true)
);
}
三、SpringMVC的跳转和乱码处理
===============================================
1、请求转发
/* 5.测试spring的请求转发
* 需求:从 /testForward 转发到 /hello
* 浏览器请求 /testForward --转发(地址不变)--> /hello
* /hello对应的方法 --转发(地址不变)--> home.jsp
*/
@RequestMapping("/testForward")
public String testForward() {
System.out.println( "testForward方法执行了...." );
return "forward:/hello";
}
请求转发总结:转发只能是同一个应用内部的资源之间进行跳转:
(1)从Controller中的一个方法转发到另外一个方法:
return "forward:/方法上的映射路径";
(2)从Controller中的方法转发JSP:
return "JSP的名字";
2、重定向
/* 5.测试spring的重定向
* 需求:从 /testRedirect 重定向到 /hello
* 浏览器请求 /testRedirect --重定向(地址会变)--> /hello
* /hello对应的方法 --转发(地址不变)--> home.jsp
*/
@RequestMapping("/testRedirect")
public String testRedirect() {
System.out.println( "testRedirect方法执行了...." );
//return "redirect:/hello";
return "redirect:http://www.baidu.com";
}
重定向总结:重定向在跳转时,没有限制
(1)同一个应用中的controller方法跳转到另外一个方法:
return "redirect:/方法上的映射路径";
(2)不同的两个Web应用之间的资源跳转: 从controller方法跳转到/day11/test.jsp
return "redirect:http://localhost/day11/test.jsp";
(3)不同的服务器之间的资源跳转:从controller方法跳转到百度
return "redirect:http://www.baidu.com";
3、乱码处理
Servlet中:
(1)如果是GET提交、并且tomcat为8.0以后的版本,tomcat底层已经处理了GET提交的中文乱码问题,所以GET提交在tomcat8.0以后的版本中没有乱码!
(2)如果是POST提交,无论是哪个版本的tomcat服务器,获取中文参数时都会有乱码问题,如何解决?
request.setCharacterEncoding("utf-8");
springmvc中提供了处理POST提交中文参数乱码方法:在web.xml文件中配置一个乱码处理过滤器。过滤器的配置如下:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
四、SpringMVC响应数据
===============================================
1、Model的使用
从Servlet带数据到JSP:(通过request域带数据)
request.setAttribute("xx", xxx);
request.getRequestDispatcher("xxx").forward(req,res);
从Controller带数据到JSP:(通过Model带数据)
model.addAttribute("xx", xxx);
return "xxx";
如果需要从Controller带数据到JSP,可以在Controller的方法上声明一个Model对象
Model其实底层就是request域,可以将数据存入到Model域中,再通过转发将数据带到JSP,
在JSP中取出数据进行显示!