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/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">
<!--
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
*/
@Controller
public class FormController {
// @PostMapping("/apply")
// @ResponseBody
public 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")
// @ResponseBody
public 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")
// @ResponseBody
public String apply2(Form form){
System.out.println("form = " + form);
return "SUCCESS";
}
/**
* 使用Map接受复合数据,在接受复合数据时,Map是有天生缺陷的
* 如果你的表单中存在复合数据时,Map 是无法接受的
* Map默认情况下只会把数组中的第一项元素进行返回
* 如果出现了复合数据,一定不能使用Map。否则数据一定会丢失
* @param map
* @return
*/
@PostMapping("/apply")
@ResponseBody
public 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")
@ResponseBody
public 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")
@ResponseBody
public 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> {
@Override
public 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注解则以注解优先