400错误:往往是无法将数据转换成目标类型所导致的
| 内容 | 说明 | 重要程度 |
|---|---|---|
| Spring MVC入门 | SPring MVC开发流程与环境配置 | ※※※※※ |
| 接受Web数据 | Spring MVC参数接受与数据绑定 | ※※※※※ |
| URL Mapping | 讲解URL绑定过程 | ※※※※※ |
| 中文乱码问题 | 解决请求与响应中文乱码 | ※※※※※ |
| 拦截器 | Spring MVC拦截器的使用 | ※※※ |
| Restful风格介绍 | 介绍Restful开发规范 | ※※※※※ |
| Restful开发实战 | 实例讲解Restful在Spring MVC中的实现 | ※※※※※ |
| JSON序列化 | 通过响应输出数据 | ※※※※※ |
| Restful的跨域问题 | 分析跨域问题的来源和解决方法 | ※※※※※ |
1、Spring MVC入门
1.1、Spring MVC介绍
1.1.1、MVC到底是什么?
- MVC(不是设计模式)是一种著名的架构模式 ,M(模型 Model)数据(在Java代码中就是业务逻辑的部分)、V(视图View)界面部分、C(控制器Controller)中介,接受视图中所传入的数据,再根据后端的业务逻辑得到结果。然后再通过控制器将后端的结果返回到视图中
- 视图和模型之间没有连接关系,一切都是通过控制器进行调用和返回的(Servlet就是用于开发控制器的技术)。由于Servlet开发非常不方便,所以Spring机构开发了Spring MVC,帮我们以更简单的方式完成Web应用的开发
- Spring MVC的用途:简化Web应用程序的开发
- Spring MVC是Spring 体系的轻量级的Web MVC框架,用来替代传统的j2EE 的Servlet进行大规模Web应用程序的开发
- Spring MVC的核心是Controller控制器,用于处理请求,产生响应。
Spring MVC基于Spring IOC容器运行,所有对象被IOC管理。
1.2、Spring MVC环境配置
1.2.1、IDEA环境下创建Maven WebApp
1.2.2、Spring MVC环境配置
Maven依赖spring-webmvc
web.xml配置DispatcherServlet
<?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"><!--DispatchServlet:对所有请求进行拦截--><servlet><servlet-name>springmvc</servlet-name><!--DispatcherServlet是Spring MVC最核心的对象(相当于前台客服)DispatcherServlet用于拦截HTTP请求,并根据请求的URL调用与之对应的Controller方法,来完成Http请求的处理--><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--applicationContext.xml--><init-param><!--上下文配置路径--><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></init-param><!--SpringMVC底层所有的对象都依赖于Spring IOC容器在Web应用启动的时候自动创建Spring IOC容器,并初始化DispatcherServlet。不写这个配置,自动创建Spring IOC容器并初始化DispatcherServlet会在第一次访问URL的时候进行为了提高程序的响应速度,一般写此配置--><load-on-startup>1</load-on-startup></servlet><!--servlet映射--><servlet-mapping><servlet-name>springmvc</servlet-name><!--"/"代表拦截所有请求--><url-pattern>/</url-pattern></servlet-mapping></web-app>
配置applicationContext的mvc标记
<?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" xmlns:mv="http://www.springframework.org/schema/mvc"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 标签作用在Spring IOC初始化过程中,自动创建并管理com.imooc.sprigmvc及子包中拥有以下注解的对象@Component : 通用@Controller :控制器类@Service :业务逻辑类@Repository--><context:component-scan base-package="com.imooc.springmvc"/><!--启用Spring MVC的注解开发模式--><mvc:annotation-driven/><!--将图片/JS/CSS等静态资源排除在外,可提高执行效率--><mvc:default-servlet-handler/></beans>
开发Controller控制器 ```java @Controller public class TestController { @ResponseBody //直接向响应输出字符串数据,不进行页面的跳转 @GetMapping(“/test”) public String test() {
return "Hello Spring MVC";
} }
<a name="nHneX"></a>## 2、Spring MVC数据绑定如何从请求中获取数据,如何将数据返回<a name="GmmTP"></a>### 2.1、URL Mapping(URL映射)- URL Mapping指将URL与Controller方法进行绑定- 通过将URL与方法绑定,SpringMVC便可通过Tomcat对外暴露服务,对外暴露的都是一个个的URL。- URL Mapping注解- @RequestMapping- 通用绑定注解- @GetMapping-绑定Get请求- @PostMapping-绑定Post请求<a name="fcc1V"></a>### 2.2、接受请求参数- 接受请求参数的常见做法- 使用Controller方法参数接受- 使用Java Bean 接受数据:可以同时完成JavaBean的创建和数据注入的工作- 接受表单复合数据- 利用数组或者List接受请求中的复合数据- 利用@RequestParam为参数设置默认值- 使用Map对象接受请求参数及注意事项- URI绝对路径与相对路径- URI是统一资源定位符的意思,是我们平时使用URL的一个子集,简单来说就是把主机和端口去掉(URL的前半部分),只留下对应资源的路径- ```java/*** 使用集合接受数据必须要加上注解 @RequestParam*/@Controllerpublic class FormController {// @PostMapping("/apply")// @ResponseBodypublic String apply(@RequestParam(value = "name",defaultValue = "ANON") String name, String course, Integer[] purpose){System.out.println(name);System.out.println(course);for (Integer p : purpose) {System.out.println(p);}return "SUCCESS";}/*** 复合数据一定要加 @RequestParam List会默认实例化为ArrayList,* @param name* @param course* @param purpose* @return*/// @PostMapping("/apply")// @ResponseBodypublic String apply1(@RequestParam(value = "name",defaultValue = "ANON") String name, String course, @RequestParam List<Integer> purpose){System.out.println(name);System.out.println(course);for (Integer p : purpose) {System.out.println(p);}return "SUCCESS";}/*** 在使用实体类接受复合数据时,可实力类中可以有List用于接受复合数据* @param form* @return*/// @PostMapping("/apply")// @ResponseBodypublic String apply2(Form form){System.out.println("form = " + form);return "SUCCESS";}/*** 使用Map接受复合数据,在接受复合数据时,Map是有天生缺陷的* 如果你的表单中存在复合数据时,Map 是无法接受的* Map默认情况下只会把数组中的第一项元素进行返回* 如果出现了复合数据,一定不能使用Map。否则数据一定会丢失* @param map* @return*/@PostMapping("/apply")@ResponseBodypublic String apply3(@RequestParam Map map){System.out.println("map = " + map);return "SUCCESS";}}
2.3、关联对象赋值
关联对象:在一个对象中引入了另外一个对象,关联对象赋值就是对被引用对象进行赋值的操作 关联对象赋值:需要将关联对象的对象名放入到原有表单 name属性的前面,作为前缀,这样Spring MVC 就能自动完成赋值的操作
前端代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>学员调查问卷</title><style>.container {position: absolute;border: 1px solid #cccccc;left: 50%;top: 50%;width: 400px;height: 600px;margin-left: -200px;margin-top: -300px;box-sizing: border-box;padding: 10px;}h2{margin: 10px 0px;text-align: center;}h3{margin: 10px 0px;}</style></head><body><div class="container"><h2>学员调查问卷</h2><form action="./apply" method="post"><h3>您的姓名</h3><input name="name" class="text" style="width: 150px"><h3>您正在学习的技术方向</h3><select name="course" style="width: 150px"><option value="java">Java</option><option value="h5">HTML5</option><option value="python">Python</option><option value="php">PHP</option></select><div><h3>您的学习目的:</h3><input type="checkbox" name="purpose" value="1">就业找工作<input type="checkbox" name="purpose" value="2">工作要求<input type="checkbox" name="purpose" value="3">兴趣爱好<input type="checkbox" name="purpose" value="4">其他</div><h3>收货人</h3><input type="text" name="delivery.name" class="text" style="width: 150px;"><h3>联系电话</h3><input type="text" name="delivery.mobile" class="text" style="width: 150px;"><h3>收货地址</h3><input type="text" name="delivery.address" class="text" style="width: 150px;"><div style="text-align: center;padding-top:10px" ><input type="submit" value="提交" style="width:100px"></div></form></div></body></html>
后端代码
@PostMapping("/apply")@ResponseBodypublic String applyDelivery(Form form) {System.out.println("form = " + form);return "SUCCESS";}public class Form {private String name;private String course;private List<Integer> purpose;/*** 对于引用对象而言,必须在当前类中对其进行实例化,这样才能保证赋值的成功* 试过了,不加也可以成功赋值*/private Delivery delivery;
2.4、日期类型转换
在日期参数前加上@DateTimeFormat注解即可,括号中要传入转换的格式pattern
@PostMapping("/applyDate")@ResponseBodypublic String applyDate(String username, String password, @DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime) {System.out.println("username = " + username);System.out.println("password = " + password);System.out.println("createTime = " + createTime);return "Success";}
在对象中的转换 ```java
public class User { private String username; private String password; @DateTimeFormat(pattern = “yyyy-MM-dd”) private Date createTime;
- 全局的日期转换器```java/*** 自定义的日期转换器:必须实现转换器接口 Converter* 转换器接口需要设置两个泛型,第一个是要转换的类型,第二个是目标类型*/public class MyDateConverter implements Converter<String,Date> {@Overridepublic Date convert(String s) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");try {Date date = simpleDateFormat.parse(s);return date;} catch (ParseException e) {e.printStackTrace();return null;}}}<context:component-scan base-package="com.imooc.springmvc"></context:component-scan><mvc:annotation-driven conversion-service="conversionService"/><mvc:default-servlet-handler/><!--转换服务的工厂Bean--><bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionService"><property name="converters"><set><bean class="com.imooc.springmvc.converter.MyDateConverter"/></set></property></bean>
如果既定义了转换器,又加上了@DateTimeFormat注解则以注解优先
