Spring MVC详解
文章目录
一、SpringMVC
1.1 引言
java开源框架,Spring Framework的一个独立模块。
MVC框架,在项目中开辟MVC层次架构
对控制器中的功能 包装 简化 扩展践行工厂模式,功能架构在工厂之上
1.2 MVC架构
1.2.1 概念
名称 | 职责 |
---|---|
Model | 模型:即业务模型,负责完成业务中的数据通信处理,对应项目中的 service和dao |
View | 视图:渲染数据,生成页面。对应项目中的Jsp |
Controller | 控制器:直接对接请求,控制MVC流程,调度模型,选择视图。对应项目中的Servlet |
1.2.2 好处
MVC是现下软件开发中的最流行的代码结构形态;
人们根据负责的不同逻辑,将项目中的代码分成 M V C 3个层次;
层次内部职责单一,层次之间耦合度低;
符合低耦合 高内聚的设计理念。也实际有利于项目的长期维护。
二、开发流程
2.1 导入依赖
<dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-webmvcartifactId> <version>5.1.6.RELEASEversion>dependency>
2.2 配置核心(前端)控制器
作为一个MVC框架,首先要解决的是:如何能够收到请求!
所以MVC框架大都会设计一款前端控制器,选型在 Servlet 或 Filter两者之一,在框架最前沿率先工作,接收所有请求。
此控制器在接收到请求后,还会负责springMVC的核心的调度管理,所以既是前端又是核心。
<servlet> <servlet-name>mvcservlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class> <init-param> <param-name>contextConfigLocationparam-name> <param-value>classpath:mvc.xmlparam-value> init-param> <load-on-startup>1load-on-startup>servlet><servlet-mapping> <servlet-name>mvcservlet-name> <url-pattern>/url-pattern>servlet-mapping>
2.3 后端控制器
等价于之前定义的Servlet
@Controller //声明这是一个控制器@RequestMapping("/hello") //访问路径 ,等价于url-patternpublic class HelloController {@RequestMapping("/test1") //访问路径public String hello1(){System.out.println("hello world");return "index"; // 跳转:/index.jsp }@RequestMapping("/test2") //访问路径public String hello2(){System.out.println("hello c9");return "views/users";// 跳转:/views/user.jsp}}
2.4 配置文件
默认名称:核心控制器名-servet.xml 默认位置:WEB-INF
随意名称:mvc.xml 随意位置:resources 但需要配置在核心控制器中
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.qf.controller">context:component-scan><mvc:annotation-driven>mvc:annotation-driven><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/">property><property name="suffix" value=".jsp">property>bean>beans>
2.5 访问
http://localhost:8989/hello/test1http://localhost:8989/hello/test2
接口方法的返回值:
- 没有返回值
- 返回逻辑视图名
- 返回字符串
- 返回 JSON
三、接收请求参数
3.1 基本类型参数
请求参数和方法的形参 同名即可
springMVC默认可以识别的日期字符串格式为: yyyy/MM/dd HH:mm:ss
通过@DateTimeFormat可以修改默认日志格式
// id name gender// http://localhost:8989/xxx/../test1?id=1&name=zzz&gender=false&birth=2018-12-12 12:20:30@RequestMapping("/test1")public String testParam1(Integer id, String name, Boolean gender, @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")Date birth){ System.out.println("test param1"); return "index";}
3.2 实体收参【重点
】
请求参数和实体的属性 同名即可
public class User {private Integer id;private String name;@DateTimeFormat(pattern="yyyy-MM-dd")private Date birth;private Boolean gender;//set/get ...}//http://localhost:8989/.../test2?id=1&name=zzz&gender=false&birth=2018-12-12 12:20:30@RequestMapping("/test2")public String testParam2(User user){ System.out.println("test param2"); System.out.println("user:"+user); return "index";}
3.3 数组收参
简单类型的 数组
<form> ...... <input type="checkbox" name="hobby" value="fb"/>足球 <input type="checkbox" name="hobby" value="bb"/>篮球 <input type="checkbox" name="hobby" value="vb"/>排球 form>
//http://localhost:8989/.../test3?hobby=football&hobby=basketball@RequestMapping("/test3")public String testParam3(String[] hobby){ for(String h:hobby){ System.out.print(h+" "); } return "index";}
3.4 集合收参 【了解】
public class UserList {//private User[] users;private List<User> users;//set/get..}// // post请求:http://...?users[0].id=1&users[0].name=zhangsan&users[0].birth=2018-12-12&users[1].id=2&....@RequestMapping("/test4")public String testParam4(UserList userList){ for(User user:userList.getUsers()){ System.out.println(user); } return "index";}
3.5 路径参数
// {id} 定义名为id的路径;【/hello/{id}】的匹配能力和【/hello@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {ex.printStackTrace();//打印异常栈//创建一个ModelAndViewModelAndView mv = new ModelAndView();//识别异常if (ex instanceof Exception1) {mv.setViewName("redirect:/xxx/error1");}else if(ex instanceof Exception2){mv.setViewName("redirect:/xxx/error2");}else{mv.setViewName("redirect:/xxx/error");}return mv;}}
<bean class="com.baizhi.exception.resolver.MyExResolver">bean>
九、拦截器
和过滤器的区别:
- 执行时机:拦截器晚于过滤器。
- 拦截器是一种 AOP 风格的过滤器。
9.1 作用
作用:抽取handler中的冗余功能
9.2 定义拦截器
执行顺序: preHandle–postHandle–afterCompletion
public class MyInter1 implements HandlerInterceptor{//主要逻辑:在handler之前执行:抽取handler中的冗余代码@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {System.out.println("pre~~~"); return true;//放行,后续的拦截器或handler就会执行}//在handler之后执行:进一步的响应定制@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {System.out.println("post~~");}//在页面渲染完毕之后,执行:资源回收@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {System.out.println("after~~");}}
9.3 配置拦截路径
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/inter/test1"/> <mvc:mapping path="/inter/test2"/> <mvc:mapping path="/inter/test*"/> <mvc:mapping path="/inter }function delUser(){ // 发送删除请求 var xhr = new XMLHttpRequest(); //定义 put,delete,get,post方式 即可,不用定义_method xhr.open("delete","${pageContext.request.contextPath}/rest04/users/1"); xhr.send(); xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200){ var ret = xhr.responseText; console.log(JSON.parse(ret)); } } }script>
十四、跨域请求
14.1 域
域:协议+IP(域名)+端口
http://localhost:8989
http://localhost:8080
http://www.baidu.com:80
14.2 Ajax跨域问题
Ajax发送请求时,不允许跨域,以防用户信息泄露。
当Ajax跨域请求时,响应会被浏览器拦截(同源策略),并报错。即浏览器默认不允许ajax跨域得到响应内容。
互相信任的域之间如果需要ajax访问,(比如前后端分离项目中,前端项目和后端项目之间),则需要额外的设置才可正常请求。
14.3 解决方案
允许其他域访问
在被访问方的Controller类上,添加注解
@CrossOrigin("http://localhost:8080") //允许此域发请求访问public class SysUserController {....}
携带对方cookie,使得session可用
在访问方,ajax中添加属性:withCredentials: true
$.ajax({ type: "POST", url: "http://localhost:8989/web/sys/login", ..., xhrFields: { // 跨域携带cookie withCredentials: true }});或var xhr = new XMLHttpRequest();// 跨域携带cookiexhr.withCredentials=true;
十五、SpringMVC执行流程
十六、Spring整合
16.1 整合思路
此时项目中有两个工厂
- DispatcherServlet 启动的springMVC工厂==负责生产C及springMVC自己的系统组件
- ContextLoaderListener 启动的spring工厂==负责生产其他所有组件
- springMVC的工厂会被设置为spring工厂的子工厂,可以随意获取spring工厂中的组件
- 整合过程,就是累加:代码+依赖+配置。然后将service注入给controller即可
16.2 整合技巧
Spring 是一个父容器,SpringMVC 是一个子容器,子容器中可以访问父容器的组件,父容器不可以访问子容器的组件。
例如,我们将 Service、Dao、Component 都注册到 Spring 容器中,将 Controller 注册到 SpringMVC 容器中,则在 Controller 中,可以注入 Service、Dao、Component ;但是 Service、Dao、Component 中无法注入 Controller。
两个工厂不能有彼此侵入,即,生产的组件不能有重合。
<context:component-scan base-package="com.zhj" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>context:component-scan>
<context:component-scan base-package="com.zhj" use-default-filters="true"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>context:component-scan>
服务端数据校验:http://springmvc.javaboy.org/2019/1112/validation
来源地址:https://blog.csdn.net/a2285786446/article/details/132477081
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341