文章目录
SpringMVC
1.作用
- 接受前台或者其他服务的数据并校验
- 返回数据到前台或者其他服务
- 指定跳转的页面或其他服务数据接口
2.搭建
2.1导入jar包
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source> <!-- 源代码使用jdk1.8支持的特性 -->
<target>1.8</target> <!-- 使用jvm1.8编译目标代码 -->
<compilerArgs> <!-- 传递参数 -->
<arg>-parameters</arg>
<arg>-Xlint:unchecked</arg>
<arg>-Xlint:deprecation </arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
2.2详解配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置spring创建容器时要扫描的包 -->
<context:component-scan base-package="cn.cdqf.web"></context:component-scan>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".html"></property>
</bean>
<!-- 配置spring开启注解mvc的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
2.3配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- SpringMVC的核心控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--避免springmvc拦截以html结尾的请求-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
2.4代码执行
@Controller
public class UserController {
@RequestMapping("index")
public ModelAndView index(ModelAndView modelAndView){
System.out.println("hello");
modelAndView.setViewName("a");
return modelAndView;
}
}
3.核心流程分析
DispacthServlet:中央控制
handlerMapping:描述是url与method的对应关系
容器加载的时候会加载到springmvc.xml,在根据springmvc.xml中配置扫描路径,就可以找到对应包,找到包以后会遍历该包下面所有类,判断类上面是否有@controller注解,如果有就放在IOC容器中,springmvc会从IOC容器中拿出所有被@controller注解修饰的类,遍历这些类的方法,拿到method对象,通过反射获得method对象上面@requestMapping注解,获得@requestMapping注解的value,就是一个url,就会把这个url与当前方法, new HandlerMapping(url,method) 放在一个List:存储了当前项目所有url以及url与method的对应关系
url---- DispacthServlet-----把这个给,就会拿到这个,去判断是否有这个,如果没有,如果有就拿到这个方法
4.ModelAndView
返回前台:
- 包含数据,request/session.setAttribute(“user”,user对象)
- 指定跳转页面 request forward方法(请求转发) response.sendRedicet(重定向)
模型视图对象:modelAndView 就是把上面两步封装到一起
addObject()方法:添加数据 添加的数据 放在request作用域 viewName:视图名称
@RequestMapping("index")
//封装了 ModelAndView 当返回String的时候 springmvc会去创建modelandview.setviewName("index")
public String index(){
System.out.println("来了,老弟");
return "index";
}
@RequestMapping("index2")
//直接放在这儿
public ModelAndView index2(ModelAndView modelAndView){
System.out.println("来了,老弟");
//request.setAttribute("username","张三") 数据
modelAndView.addObject("username","张三");
//指定跳转的页面
modelAndView.setViewName("index");
return modelAndView;
}
5.json参数返回
4.1详解配置
jsp的前后端耦合性太强,不适用于高度解耦的前后端分离的开发。
json是作为前后端的数据交互的重要数据载体
-
导入fastjson.jar
-
配置springmvc.xml中的json转换器
- 编码问题
- 配置前后端下载文件冲突
- 属性值为null转换输出配置
- 日期格式
- 循环调用问题
<!-- 配置spring开启注解mvc的支持--> <mvc:annotation-driven></mvc:annotation-driven> <mvc:annotation-driven> <!--不使用默认消息转换器 --> <mvc:message-converters register-defaults="false"> <!--spring消息转换器 --> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/> <!--解决@Responcebody中文乱码问题 --> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <!--配合fastjson支持 --> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="defaultCharset" value="UTF-8"/> <property name="supportedMediaTypes"> <list> <!--顺序保持这样,避免IE下载出错 配置1.注意编码 2.注意与下载文件冲突--> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="fastJsonConfig" ref="fastJsonConfig"/> </bean> </mvc:message-converters> </mvc:annotation-driven> <!--fastJsonConfig 这里面的配置需要开发中 跟前端进行协商--> <bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig"> <!--默认编码格式 --> <property name="charset" value="UTF-8"/> <property name="serializerFeatures"> <list> <!--3.需要指定null按照协商好的配置返回--> <!-- List字段如果为null,输出为[]--> <value>WriteNullListAsEmpty</value> <!--4.日期格式 使得返回的日期类型默认为yyyy-MM-dd hh:mm:ss --> <value>WriteDateUseDateFormat</value> <!--美化格式--> <value>PrettyFormat</value> <value>WriteMapNullValue</value> <value>WriteNullStringAsEmpty</value> <!--禁止循环引用检测 Teacher : List<Student> Student : Teacher stackOverFlow: --> <value>DisableCircularReferenceDetect</value> </list> </property> </bean>
-
导入前端js,css等静态资源,配置放过拦截js
<!-- 对指定目录下的静态资源放行(**代表当前文件夹及子文件夹所有文件) --> <mvc:resources location="/fonts/" mapping="/fonts/**"/> <mvc:resources location="/css/" mapping="/css/**"/> <mvc:resources location="/js/" mapping="/js/**"/>
4.2 基本数据类型
4.3 String类型
后端代码:
@Controller
//namespace作用 handlerMapping: url=类上面+方法上
@RequestMapping("ajax")
//@RestController=@Controller+@ResponseBody
public class AjaxController {
//8888/ajax/ajax1
@RequestMapping("ajax1")
//如果不告诉springmvc返回json 默认返回字符串是代表路径
@ResponseBody//就是告诉springmvc 这个方法得返回值是一个json springmvc就会调用配置json库
// 来进行转换为json字符串然后通过 response.getwriter写回去
public String ajax1(){
System.out.println("ajax1方法被请求");
return "hello ajax1";
}
}
public String index(){
System.out.println("来了,老弟");
//转发
return "forward:index";//forward默认省略 等于return “index"
//重定向
return "redirect:/WEB-INF/pages/index.html";
}
- 请求转发的字符串若在springmvc.xml文件中配置了viewResolver将为其加上前缀和后缀进行请求
- 重定向的字符串路径则需要手动拼接
前端代码:
<link href="/css/bootstrap.min.css">
<script src="/js/jquery-3.3.1.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</head>
<body>
<button id="ajax">点击</button>
</body>
<script>
$(function () {
$("#ajax").click(function () {
$.ajax({
url:"/ajax/ajax1",
type:"GET",
dataType:"json",//返回数据类型
success:function (data) {
console.log(data);
}
})
})
})
</script>
4.4集合类型
4.5Map类型
4.6数组类型
4.7日期类型
4.8实体对象
@RestController
@RequestMapping("student")
public class Ajax2Controller {
@RequestMapping("ajax1")
public List<Student> ajax1(){
return Arrays.asList(new Student("张三", "力宝", new Date(), 100), new Student("李四", "力宝", new Date(), 100));
}
}
5.其他配置
5.1配置过滤器
<!-- 配置过滤器,解决中文乱码的问题 -->
<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>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5.2日期转换配置
-
创建日期转换类实现Converter接口
public class DateConverter implements Converter<String, Date> { @Override public Date convert(String s) { if(s !=null){ try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); return dateFormat.parse(s); } catch (ParseException e) { e.printStackTrace(); } } return null; } }
-
xml配置
<!--配置自己写好的转换器--> <bean id="dateConverter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.ctbu.converter.DateConverter"/> </list> </property> </bean> <!--配置注解驱动,让转换器生效--> <mvc:annotation-driven conversion-service="dateConverter"/>
5.3拦截器配置
-
创建自定义拦截器,实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor { /** * @param request * @param response * @param handler * @return * @throws Exception * 在controller方法之前执行 * * 1.return true就执行controller *2. return false就不会执行controller */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //用户没有登录 让用户跳转到登录页面 //response.sendRedirect("http://localhost:8888/login.html"); //response也可以写json //拿到url 拿到参数 获得session 获得cookie //某些请求需要等 某些不登录 queryAllProduct 不需要登录 updateProduct需要登录 //通过request获得url 看一看是不是需要登录的请求 从session中获得登录信息 就可以判断 //不同的角色 在项目 权限不同 deleteUser //url:login----LoginController中 login方法 //HttpMethod handler1 = (HttpMethod) handler; System.out.println("拦截器执行了....."); return true; } //modelAndView :1.会有数据携带 2.跳转的页面 //html中 ${abc} 取出request.setAttribute("abc","张三") //视图渲染:把页面中占位符替换为 值 页面html元素 与数据的整合 //1.会在视图渲染前执行,可以去修改视图渲染的值 //正常情况下 postHandle先执行 afterCompletion后执行 // postHandle出现异常不会执行 afterCompletion出现异常也会执行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle执行了"); } //2.会在视图渲染后执行 //可以获得当前请求出现异常 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion执行了"); } }
-
xml拦截器配置(多个拦截器)
<mvc:interceptors> <mvc:interceptor> <!--当前拦截器 要拦截的路径--> <mvc:mapping path="/**"/> <!--在上面的路径中排除某些路径--> <mvc:exclude-mapping path="/interceptor/index3"/> <bean class="cn.cdqf.web.interceptor.MyInterceptor"/> </mvc:interceptor> <mvc:interceptor> <!--当前拦截器 要拦截的路径--> <mvc:mapping path="/**"/> <!--在上面的路径中排除某些路径--> <mvc:exclude-mapping path="/interceptor/index3"/> <bean class="cn.cdqf.web.interceptor.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
6.请求参数
6.1@RequestParam注解
-
基本类型
- 基本数据类型作为请求方法的参数时,参数名必须一致
- 前台传入的数据为空将抛出类型转换异常,返回400错误(参数有误)。若为包装类型则会将null作为值传入
- 使用@RequestParam替换参数名
-
数组/集合类型
配置@RequestParam注解
//@RequestParam中的value必须在对应的名称后面加[]表示接受数组或者集合类型 //用@RequestParam标注表示必须传一个名字相同的参数 public void insert(@RequestParam(value = "ids[]",required = false) String[] ids, @RequestParam("name") String username) { }
6.2@Requestbody注解
-
标注在方法上表示方法将返回json数据
@RestController=@Controller+@ResponseBody
-
标注在参数上表示参数为接受json数据
- 前端请求参数类型为json字符串
- 请求方法为Post
- 请求头中的ContentType=“application/json”,表示Http响应回来的是json数据
7.HTTP常见Code编号
编号 | 概述 |
---|---|
404 | 请求路径错误 |
400 | 请求参数错误 |
405 | 请求方法错误,前后端GET/POST方法不一致 |
302 | 重定向 |
304 | 浏览器缓存 |
500 | 后台服务器错误 |