问题三连?
为什么引入SpringMVC?
用Servlet它不香吗?
SpringMVC原理是什么?
Servlet的缺点 :
- 请求参数需要一个一个的手动获取,来个对象带20个属性你手动获取试试看?
- 请求参数都是String类型,需要手动进行数据类型转换
- Servlet由tomcat创建,存在tomcat容器,dao和service由spring容器管理,无法在Servlet注入service,需要手动获取service层的bean和getBean()
- 页面转发,重定向,调用web层相关对象,往前端发送json数据,只能手动使用json-lib转换,调用response的响应流写给前端
- 一个功能对应一个Servlet,一个客户端起码几十个功能,那就起码几十个类,who can who up
而SpringMVC能够解决上面所有问题…
SpringMVC是一种基于Java的实现了Web MVC设计模式的请求驱动
类型的轻量级web框架
以下是SpringMVC的工作流程
1、 用户发送请求至前端控制器DispatcherServlet。(前端控制器)
2、 DispatcherServlet收到请求调用HandlerMapping。(处理器映射器)
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。(前端控制器),返回一个执行链。
4、 DispatcherServlet调用HandlerAdapter。(处理器适配器)
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 处理器适配器查找处理器执行执行链
7、执行处理器,即Controller执行完成,返回ModelAndView。(类似支持视图名称和视图对象) ,这里其实就是JSP里的EL表达式等,我们最终显示在客户端的必须是数值,而不是表达式。
8、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
9、 DispatcherServlet将ModelAndView传给前端控制器再传到ViewReslover。(视图解析器)
10、ViewReslover解析后返回具体View。(视图)到前端控制器里
11、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。也就是将EL表达式的内容解析成数据到视图
12、响应前端
SpringMVC入门的导入配置文件
*Spring配置文件
Springmvc的配置文件(与spring配置一模一样)
Mybatis配置文件
Sql映射文件
log4j配置文件
db配置文件*
1.Jar包准备,版本可以个人选择,尽量不要选择最新版本,因为稳定性不高
包名 | 作用 |
---|---|
spring-context | spring框架 |
jstl | jstl标签 |
spring-aspects | aop实现的框架 |
spring-test | spring与junit整合 |
junit | junit测试 |
slf4j-log4j12 | 日志 |
spring-web | spring与web整合的jar |
mybatis | mybatis框架 |
ojdbc14 | Oracle的驱动jar |
c3p0 | c3p0连接池 |
javax.servlet-api | servlet的jar |
jsp-api | jsp的jar |
mybatis-spring | mybatis与spring整合的jar |
spring-orm | spring与orm模型整合 |
spring-tx | 事务jar |
spring-webmvc | springmvc |
2.配置web.xml文件,配置springmvc的控制器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置springmvc的前端控制器 创建springmvc的容器 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--如果不配置contextConfigLocation,默认查找springmvc的配置文件为:WEB-INF/servlet名字-servlet.xml -->
<!--比如我们这查找的就是:WEB-INF/springMVC-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- spring默认加载的配置文件: web-inf/springmvc-servlet.xml -->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- servlet创建在tomcat启动时创建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!-- url-pattern有三种配置方式: 1. *.action, springMVC的前端控制器只处理以action结尾的url请求
2. / 所有请求都由springMVC的前端控制器处理, 但是对于静态资源我们不然让前端控制器处理,所以我们需要进行配置, 使用这种配置方式,可以实现restful风格
3. /* 错误 -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 配置初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 设置响应编码 -->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.添加springmvc的配置文件,默认在src下添加dispatcherServletName-servlet.xml
<beans
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans">
<!-- springMVC的配置文件 -->
<!-- 视图解析器 : 使用它根据逻辑视图 list,找物理视图视图类型: jsp 使用转发到视图 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property value="/jsp/" name="prefix" />
<!-- 后缀物理视图: 前缀 + 逻辑视图名 + 后缀 -->
<property value=".jsp" name="suffix" />
<!-- 视图的类 : 视图支持 jstl -->
<property
value="org.springframework.web.servlet.view.JstlView"
name="viewClass" />
</bean>
<!-- 基于注解的处理器映射器,处理器适配器 -->
<mvc:annotation-driven />
<!-- 扫描注解 -->
<context:component-scan
base-package="rentRoomCom.web" />
<!-- <context:component-scan base-package="spring08"><context:include-filter
type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan> -->
4.编写Controller类
@Controller
public class HelloController {
public ModelAndView addUser throws Exception {
//ModelAndView类是封装要显示到页面的数据
//之后不用new的方式,会使用注解的形式实现对象创建
ModelAndView mav=new ModelAndView();
//页面的数据
mav.addObject("name","hellospringmvc");
//配置视图名称
mav.setViewName("hello);
return mv;
}
这里值得一提的是,在Servlet中我们还需要通过过滤器或者response.setContentType(“text/html;charset=utf-8”)这样的方式来限制编码格式
而在Spring中为开发者提供了乱码过滤器,只需要配置就可以了,但是Spring提供的只能处理post请求的编码,以及相应编码
而get请求编码需要在tomcat的servlet.xml文件中配置 : URLEncoding=“UTF-8”,而同时在tomcat8以上的版本以及处理完毕了,如果版本比较新的可以忽略
<!-- 配置处理乱码的过滤器: post请求编码, 响应编码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 配置初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 设置响应编码 -->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置方面到这基本讲完了,以下是注解方面
- @RequestMapping
加在方法上,给处理用户的方法绑定一个url
属性 : value/path 绑定url
method 默认的get/post请求都能处理,这里的method是枚举类型
加在类上, 作为url的上级目录,也就是窄化了请求
例子 :
@Controller
@RequestMapping("/user")
public class HelloController {
方法{
//方法体...
}
}
这个Controller类的方法url前面都要加上 /user/前缀
例如 : localhost:8888/包名/user/前缀
- @GetMapping("/sayHello.action")
这个注解只能加在方法上,意思是给方法绑定一个url,但是处理请求方式只能是get请求
@PostMapping("/sayHello.action")
这个注解也只能加在方法上,意思是给方法绑定一个url,处理请求方法只能是post请求
值得注意的是 : 如果前端没有传递相同名字的name的数据类型,springmvc会默认给参数赋值为空
如果参数是基本数据类型,此时会报错,因为基本数据类型是不能接收空值的
- @RequestParam
这个注解一般写在方法参数前面
例如 :
@RequestMapping("/method.action")
public ModelAndView method(@RequestParam(name="userId")int it) throws Exception {
//这个方法中参数的注解意思是--把请求参数的name为userId的值传给it
//如果请求参数的name域方法参数名不一致时,可以使用这个注解进行映射
//这个注解有三个属性 defaultValue="2" 如果这个参数没有这个name值,默认值是2
// value/name 请求参数的name
// required 值为true时要求前端必须要有这个值
}
-
@PathVariable 映射 加在RestFull风格的url占位符(这个用的少)
-
@ModelAttribute
这个注解加在方法上 表示这个方法在每一次处理器处理方法执行之前都执行
如果这个方法有返回值 会把这个返回值的结果保存到Model(默认是request域) key是这个注解的name值
加在参数上时 表示从Model中获取对应的name值 赋值给参数
- @SessionAttributes
这个注解一般是Controller类上 表示将所有存入到Model(request域)的数据存到session域
属性 : names
@SessionAttributes(names={"user"}) 把Controller类上把Model(request域)
例如 : @SessionAttributes(names={"user"})
意思是将user的对象存入Session域 其他不存入
以上的注解就是SpringMVC常用的注解
接下来BB赖赖一下,Controller方法返回值 :
- 返回的ModelAndView
ModelAndView 存放数据,addObject()往Model(request域)添加
ModelAndView添加逻辑视图名,setViewName()经过视图解析器,得到物理视图,转发到物理视图 - 返回String类型,返回视图
逻辑视图名,经过视图解析器,得到物理视图,转发
redirect : 资源路径,不经过视图解析器,要求中国资源路径写完整的路径
一般写法以/开头,表示/项目名 即重定向到资源
例子 :
@RequestMapping("/demo.action")
public String toIndex(){
//1.想跳转到index.jsp页面
return "redirect:/jsp/index.jsp";//即访问jsp文件夹下的index.jsp
//2.重定向到Controller类的某个方法
return "redirect:/user/getUser.action";//转发请求user文件夹下的注解是@RequestMapping("/getUser.action")的方法
//3.forward转发 : 资源路径(这个请求不经过视图解析器)
return "forwar:/jsp/index.jsp";
//4.响应给前端的字符串(数据) 响应数据需要结合注解@ResponseBody
4.1当返回值是Java对象的时候 结合@ResponseBody 发送json对象
4.2当返回值是void时默认逻辑视图名Controller的@RequestMapping()的前缀+方法名(这个很少用)
}
🆗
到这返回值也将完了,接下来是Controller方法的参数类型
问 : 可能很多朋友会有疑问,用Controller取代Servlet那我要操作域里的数据怎么办呢
答 : 不多BB,看代码
@RequestMapping("/demo.action")
public String demo(HttpServletRequest request,HttpServletResponse response){
request.setAttribute("hello","request_hello");
request.getSession.setAttribute("hello","session_hello");
Cookie cookie=new Cookie("haha","cookie_hello");
//把cookie保存到客户端
response.addCookie(cookie);
return "hello";
}
结果我们会看到在hello.jsp页面能够看到request,session,cookie都能获取到对应的值
所以说 : 当我们在方法体里面要用到request和repsonse时,直接方法参数那添加上就行
当我们只想对Request域存放数据时,推荐使用Model,因为这样可以让Controller类与Servlet API解耦
推荐写法
@RequestMapping("/demo.action")
public void demo(Model model){
//springmvc将model对象中的数据存到request域
//但是model对象不能替换request对象
model.addAttribute("hello","model_hello");
model.addAttribute("test","test_111");
}
接收请求参数
前端发送过来的对象数据/json格式数据,后台如何接收?
基本数据类型时
1.参数名和请求参数名一样时,自动进行映射
2.如果参数名和请求参数名不一样,用注解@RequestParam()进行映射
Java对象有属性是日期类型时(SpringMVC不能自动转换Date类型,需要手动配置/转换)
1.局部转换(只对某个日期类型生效)
在对象的属性上添加注解 @DateTimeFormat(pattern=“日期格式”)
例子 : @DateTimeFormat(pattern="yyyy-mm-dd")
2.全局转换(对整个项目的所有date类型有效),比较麻烦,除非日期类型的属性比较多,不然还是用局部转换比较简单暴力省事
请看链接–https://blog.csdn.net/cssnnd/article/details/106883719