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

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <!--DispatchServlet:对所有请求进行拦截-->
    7. <servlet>
    8. <servlet-name>springmvc</servlet-name>
    9. <!--
    10. DispatcherServletSpring MVC最核心的对象(相当于前台客服)
    11. DispatcherServlet用于拦截HTTP请求,
    12. 并根据请求的URL调用与之对应的Controller方法,来完成Http请求的处理
    13. -->
    14. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    15. <!--applicationContext.xml-->
    16. <init-param>
    17. <!--上下文配置路径-->
    18. <param-name>contextConfigLocation</param-name>
    19. <param-value>classpath:applicationContext.xml</param-value>
    20. </init-param>
    21. <!--
    22. SpringMVC底层所有的对象都依赖于Spring IOC容器
    23. Web应用启动的时候自动创建Spring IOC容器,
    24. 并初始化DispatcherServlet
    25. 不写这个配置,自动创建Spring IOC容器并初始化DispatcherServlet会在第一次访问URL的时候进行
    26. 为了提高程序的响应速度,一般写此配置
    27. -->
    28. <load-on-startup>1</load-on-startup>
    29. </servlet>
    30. <!--servlet映射-->
    31. <servlet-mapping>
    32. <servlet-name>springmvc</servlet-name>
    33. <!--"/"代表拦截所有请求-->
    34. <url-pattern>/</url-pattern>
    35. </servlet-mapping>
    36. </web-app>
  • 配置applicationContext的mvc标记

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:mvc="http://www.springframework.org/schema/mvc"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mv="http://www.springframework.org/schema/mvc"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans
    7. http://www.springframework.org/schema/beans/spring-beans.xsd
    8. http://www.springframework.org/schema/context
    9. http://www.springframework.org/schema/context/spring-context.xsd
    10. http://www.springframework.org/schema/mvc
    11. http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    12. <!--
    13. context:component-scan 标签作用
    14. Spring IOC初始化过程中,自动创建并管理com.imooc.sprigmvc及子包中拥有以下注解的对象
    15. @Component 通用
    16. @Controller :控制器类
    17. @Service :业务逻辑类
    18. @Repository
    19. -->
    20. <context:component-scan base-package="com.imooc.springmvc"/>
    21. <!--启用Spring MVC的注解开发模式-->
    22. <mvc:annotation-driven/>
    23. <!--将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
    24. <mvc:default-servlet-handler/>
    25. </beans>
  • 开发Controller控制器 ```java @Controller public class TestController { @ResponseBody //直接向响应输出字符串数据,不进行页面的跳转 @GetMapping(“/test”) public String test() {

    1. return "Hello Spring MVC";

    } }

  1. <a name="nHneX"></a>
  2. ## 2、Spring MVC数据绑定
  3. 如何从请求中获取数据,如何将数据返回
  4. <a name="GmmTP"></a>
  5. ### 2.1、URL Mapping(URL映射)
  6. - URL Mapping指将URL与Controller方法进行绑定
  7. - 通过将URL与方法绑定,SpringMVC便可通过Tomcat对外暴露服务,对外暴露的都是一个个的URL。
  8. - URL Mapping注解
  9. - @RequestMapping- 通用绑定注解
  10. - @GetMapping-绑定Get请求
  11. - @PostMapping-绑定Post请求
  12. <a name="fcc1V"></a>
  13. ### 2.2、接受请求参数
  14. - 接受请求参数的常见做法
  15. - 使用Controller方法参数接受
  16. - 使用Java Bean 接受数据:可以同时完成JavaBean的创建和数据注入的工作
  17. - 接受表单复合数据
  18. - 利用数组或者List接受请求中的复合数据
  19. - 利用@RequestParam为参数设置默认值
  20. - 使用Map对象接受请求参数及注意事项
  21. - URI绝对路径与相对路径
  22. - URI是统一资源定位符的意思,是我们平时使用URL的一个子集,简单来说就是把主机和端口去掉(URL的前半部分),只留下对应资源的路径
  23. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12460403/1612527318012-15799ce2-553f-44f8-a120-db8fbf0d2a0e.png#align=left&display=inline&height=675&margin=%5Bobject%20Object%5D&name=image.png&originHeight=675&originWidth=1132&size=245555&status=done&style=none&width=1132)
  24. ```java
  25. /**
  26. * 使用集合接受数据必须要加上注解 @RequestParam
  27. */
  28. @Controller
  29. public class FormController {
  30. // @PostMapping("/apply")
  31. // @ResponseBody
  32. public String apply(@RequestParam(value = "name",defaultValue = "ANON") String name, String course, Integer[] purpose){
  33. System.out.println(name);
  34. System.out.println(course);
  35. for (Integer p : purpose) {
  36. System.out.println(p);
  37. }
  38. return "SUCCESS";
  39. }
  40. /**
  41. * 复合数据一定要加 @RequestParam List会默认实例化为ArrayList,
  42. * @param name
  43. * @param course
  44. * @param purpose
  45. * @return
  46. */
  47. // @PostMapping("/apply")
  48. // @ResponseBody
  49. public String apply1(@RequestParam(value = "name",defaultValue = "ANON") String name, String course, @RequestParam List<Integer> purpose){
  50. System.out.println(name);
  51. System.out.println(course);
  52. for (Integer p : purpose) {
  53. System.out.println(p);
  54. }
  55. return "SUCCESS";
  56. }
  57. /**
  58. * 在使用实体类接受复合数据时,可实力类中可以有List用于接受复合数据
  59. * @param form
  60. * @return
  61. */
  62. // @PostMapping("/apply")
  63. // @ResponseBody
  64. public String apply2(Form form){
  65. System.out.println("form = " + form);
  66. return "SUCCESS";
  67. }
  68. /**
  69. * 使用Map接受复合数据,在接受复合数据时,Map是有天生缺陷的
  70. * 如果你的表单中存在复合数据时,Map 是无法接受的
  71. * Map默认情况下只会把数组中的第一项元素进行返回
  72. * 如果出现了复合数据,一定不能使用Map。否则数据一定会丢失
  73. * @param map
  74. * @return
  75. */
  76. @PostMapping("/apply")
  77. @ResponseBody
  78. public String apply3(@RequestParam Map map){
  79. System.out.println("map = " + map);
  80. return "SUCCESS";
  81. }
  82. }

2.3、关联对象赋值

关联对象:在一个对象中引入了另外一个对象,关联对象赋值就是对被引用对象进行赋值的操作 关联对象赋值:需要将关联对象的对象名放入到原有表单 name属性的前面,作为前缀,这样Spring MVC 就能自动完成赋值的操作

  • 前端代码

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>学员调查问卷</title>
    6. <style>
    7. .container {
    8. position: absolute;
    9. border: 1px solid #cccccc;
    10. left: 50%;
    11. top: 50%;
    12. width: 400px;
    13. height: 600px;
    14. margin-left: -200px;
    15. margin-top: -300px;
    16. box-sizing: border-box;
    17. padding: 10px;
    18. }
    19. h2{
    20. margin: 10px 0px;
    21. text-align: center;
    22. }
    23. h3{
    24. margin: 10px 0px;
    25. }
    26. </style>
    27. </head>
    28. <body>
    29. <div class="container">
    30. <h2>学员调查问卷</h2>
    31. <form action="./apply" method="post">
    32. <h3>您的姓名</h3>
    33. <input name="name" class="text" style="width: 150px">
    34. <h3>您正在学习的技术方向</h3>
    35. <select name="course" style="width: 150px">
    36. <option value="java">Java</option>
    37. <option value="h5">HTML5</option>
    38. <option value="python">Python</option>
    39. <option value="php">PHP</option>
    40. </select>
    41. <div>
    42. <h3>您的学习目的:</h3>
    43. <input type="checkbox" name="purpose" value="1">就业找工作
    44. <input type="checkbox" name="purpose" value="2">工作要求
    45. <input type="checkbox" name="purpose" value="3">兴趣爱好
    46. <input type="checkbox" name="purpose" value="4">其他
    47. </div>
    48. <h3>收货人</h3>
    49. <input type="text" name="delivery.name" class="text" style="width: 150px;">
    50. <h3>联系电话</h3>
    51. <input type="text" name="delivery.mobile" class="text" style="width: 150px;">
    52. <h3>收货地址</h3>
    53. <input type="text" name="delivery.address" class="text" style="width: 150px;">
    54. <div style="text-align: center;padding-top:10px" >
    55. <input type="submit" value="提交" style="width:100px">
    56. </div>
    57. </form>
    58. </div>
    59. </body>
    60. </html>
  • 后端代码

    1. @PostMapping("/apply")
    2. @ResponseBody
    3. public String applyDelivery(Form form) {
    4. System.out.println("form = " + form);
    5. return "SUCCESS";
    6. }
    7. public class Form {
    8. private String name;
    9. private String course;
    10. private List<Integer> purpose;
    11. /**
    12. * 对于引用对象而言,必须在当前类中对其进行实例化,这样才能保证赋值的成功
    13. * 试过了,不加也可以成功赋值
    14. */
    15. private Delivery delivery;

    2.4、日期类型转换

  • 在日期参数前加上@DateTimeFormat注解即可,括号中要传入转换的格式pattern

    1. @PostMapping("/applyDate")
    2. @ResponseBody
    3. public String applyDate(String username, String password, @DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime) {
    4. System.out.println("username = " + username);
    5. System.out.println("password = " + password);
    6. System.out.println("createTime = " + createTime);
    7. return "Success";
    8. }
  • 在对象中的转换 ```java

public class User { private String username; private String password; @DateTimeFormat(pattern = “yyyy-MM-dd”) private Date createTime;

  1. - 全局的日期转换器
  2. ```java
  3. /**
  4. * 自定义的日期转换器:必须实现转换器接口 Converter
  5. * 转换器接口需要设置两个泛型,第一个是要转换的类型,第二个是目标类型
  6. */
  7. public class MyDateConverter implements Converter<String,Date> {
  8. @Override
  9. public Date convert(String s) {
  10. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
  11. try {
  12. Date date = simpleDateFormat.parse(s);
  13. return date;
  14. } catch (ParseException e) {
  15. e.printStackTrace();
  16. return null;
  17. }
  18. }
  19. }
  20. <context:component-scan base-package="com.imooc.springmvc"></context:component-scan>
  21. <mvc:annotation-driven conversion-service="conversionService"/>
  22. <mvc:default-servlet-handler/>
  23. <!--转换服务的工厂Bean-->
  24. <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionService">
  25. <property name="converters">
  26. <set>
  27. <bean class="com.imooc.springmvc.converter.MyDateConverter"/>
  28. </set>
  29. </property>
  30. </bean>

如果既定义了转换器,又加上了@DateTimeFormat注解则以注解优先

2.5、解决中文乱码

  • Web应用中的中文乱码由来
    • Tomcat默认使用字符集ISO-8859-1,属于西欧字符集
    • 解决乱码的思路是将ISO-8859-1转换为UTF-8
    • Controller中请求与响应都需要设置UTF-8字符集
  • 中文乱码的配置
    • Get请求乱码-server.xml增加URIEncoding属性,Tomcat8.0以后不用配置
    • Post请求乱码-web.xml配置CharacterEncodingFilter
    • Response响应乱码-Spring配置StringHttpMessageConverter

      3、Restful开发风格

      4、Spring MVC拦截器