史上最全面的Springmvc技术教程

版权声明:原创博文,共同进步 https://blog.csdn.net/qq_37939251/article/details/82253960

springmvc

简介

springmvc是一个web层mvc框架, 何谓MVC?

model 模型

view 视图

controller 控制器

这是一种设计模式,将责任进行拆分,不同的组件负责不同的事情。

好处

  • 结构清晰

  • 更好维护(大量使用jsp的年代,<%%>,显示)

坏处

  • 更加复杂了

    扫描二维码关注公众号,回复: 2997524 查看本文章

 

目录(点击选项跳转)

springmvc

简介

入门体验

springmvc分析

/*不能写的原因

*.do的用法

/用法

关于前端控制器的解释

springmvc配置文件名字的问题

视图解析器

控制器的解释

注解开发模式

转发与重定向

关于springmvc访问web元素

注解详解

@RequestMapping

关于请求路径的问题

@GetMapping 、 @PostMaping.....

对于非get post请求的支持

@Responsebody

@ModelAttribute

@SessionAttribute

@SessionAttributes

@SessionAttribute

@RequestParam

@RequestBody

@InitBinder

@PathVariable

 

@RestController

关于静态资源访问的问题

关于post请求中文乱码问题解决

关于form表单提交数据的方式

方式一 通过属性名字绑定

方式二 利用@RequetParam

方式三 直接使用pojo形式传递

关于form表单提交日期格式数据问题的处理

 

json数据交互

额外依赖

JSON数据返回前台以及如何解析

JSON数据如何使用Ajax提交到后台,后台如何解析

关于Form提交数据与Ajax自定义JSON数据提交的区别

XML数据交互



入门体验

  1. 创建web项目(运行环境 IDEA)

  2. 编写web.xml,在其中注册一个特殊的servlet,前端控制器

  3. 编写一个springmvc的配置文件

    1. 注册一个视图解析器

  4. 编写要给控制器

  5. 编写一个结果页面

 

创建maven web项目结构如下:

pom.xml


<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.sz</groupId>
  <artifactId>springmvc01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springmvc01 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
   <!--添加springmvc的依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.8.RELEASE</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>springmvc01</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

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_3_1.xsd"
         version="3.1">


    <!--注册一个前端控制器
      DispatcherServlet

    -->
  <servlet>
    <!--这里写的这个名字是有讲究的,
      如果我们不去修改spring配置文件默认的位置,那么springmvc
         它会去web-inf下面找一个叫做springmvc-servlet.xml的文件

         -->
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>
  
  <!--servlet映射配置-->
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--这里统一写斜杠-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">
​
​
    <!--配置一个视图解析器
    常用内部资源视图解析器
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--1. 前缀-->
        <property name="prefix" value="/jsp/"/>
​
        <!--2. 后缀-->
        <property name="suffix" value=".jsp"/>
​
    </bean>
​
​
​
    <bean class="com.sz.controller.HelloController" name="/helloController">
​
    </bean>
</beans>

控制器代码

package com.sz.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 实现一个Controller接口的方式
public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mav = new ModelAndView();
        mav.addObject("girl","菲菲");
        mav.setViewName("girl");
        return mav;
    }
}

视图代码

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/8/27
  Time: 9:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    我的脑海:${girl}
</body>
</html>
​

springmvc分析

流程图

组件分析

web.xml

注册前端控制器,目的在于,我们希望让springmvc去处理所有的请求,

通过

<!--servlet映射配置-->
<servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <!--这里写斜杠-->
  <url-pattern>/</url-pattern>
</servlet-mapping>

确实是处理所有的请求(不是真的所有)

urlPattern的写法问题

  • /

  • /* (永远都不要这么写)

  • *.do

/*不能写的原因

请求 /helloController过去的时候,它的视图名称是girl,girl.jsp页面,它将其当作了一个叫girl.jsp的请求,尝试去匹配对应的controller,但是我的容器当中根本不存在这样的controller,所以无法匹配,导致404.

*.do的用法

这种方式,是有的团队习惯将请求的行为加个小尾巴用来区分,do,行为 *.action

/用法

处理所有的请求,但是和/*不一样,它处理完之后要出去的时候不会再去将这个girl.jsp当作一个新的请求,将这个渲染的结构直接返回给浏览器

关于前端控制器的解释

springmvc设计的理念是希望开发者尽量远离原生的servletAPI,API不是很好用,繁琐点,将操作进一步的简化,它将很多东西责任进行了拆分,不希望我们将一些技术点绑定死,可以做到随意的切换。本身还是基于Servlet设计的,分发的servlet.

springmvc配置文件名字的问题

默认情况下是用dispatcherServlet的名字当作命名空间

[servletName]-servlet.xml(WEB-INF)之下寻找。

[servletName]-servlet=namespace.

将配置文件移动位置之后,出现了下面的异常。

 Could not open ServletContext resource [/WEB-INF/springmvc-servlet.xml]

如果非要重新使用另外一个名字。

默认的规则要求在web-inf下,但是maven项目的标准应该在resources下面,如何解决这个问题呢?

重新制定上下文的配置文件的位置即可。

<init-param>
    <!--上下文配置的位置的制定-->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
</init-param>

此时是在类路径下寻找springmvc.xml这个配置文件,我推荐使用这种。

视图解析器

springmvc支持多种视图技术

  • jsp

  • freemaker(模板技术)

内部的资源视图解析器

  • 视图前缀

    • /jsp/ 它是我们的请求响应的资源的路径的配置, viewName : girl /jsp/girl

  • 后缀

    • .jsp 此时我们的前缀+视图名称+后缀= /jsp/girl.jsp

request.getDS.forward(request,response);的作用是一样一样的。

物理视图由逻辑视图转换而来

物理视图是 webapp/jsp/girl.jsp

逻辑视图

  • prefix

  • logicViewName

  • suffix

p View = prefix + logicViewName + suffix;

控制器的解释

是一种比较传统的实现一个接口的方式完成的,Controller。

如果要给接口只有一个方法,这种接口叫做函数式接口

@Nullable
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

他像谁?

servlet里面由doGet doPost 里面入参就是请求与响应。

void

设计为ModelAndView 。

在model当中填充数据,然后在具体的视图进行展示。

还需要在配置文件当中配置一下这个bean,要取个名字,就用来充当了这个请求URI。

它就处理一个请求,跟servlet差别不是很大。

注解开发模式

基于实现接口的方式已经是过去式了,采用注解开发很简单

基本注解

  • @Controller

  • @RequestMapping

开发步骤

  1. 记得配置一下基础扫描的包,这样配置的注解才会生效

  2. 在指定的类上面添加@Controller注解

  3. 添加@RequestMapping 类似于前面的controller的那个名字(不同requesthandler处理的 HandlerMapping

当我们写上Controller之后,就标记了它为spring的一个组件,并且是控制器的组件,此时我们的handlermapping会去扫描寻找这个controller是否与之匹配,如果发现匹配就把这里处理的工作交给它。

匹配的规则的又是什么呢?

具体的匹配就是通过请求的路径进行匹配的

@RequestMappint(URI)

此时就是通过这个URI进行匹配

@RequestMapping

可以写在方法上

类上(推荐使用二者结合的方式)

转发与重定向

  • 转发到页面 默认到选项

  • 重定向到页面 redirect:path

  • 转发到另外一个控制器 forward:path

关于springmvc访问web元素

  • request

  • session

  • application

可以通过模拟的对象完成操作,也可以使用原生的ServletAPI完成,直接在方法当中入参即可。

注解详解

@RequestMapping

  • value 写的是路径,是一个数组的形式,可以匹配多个路径

  • path 是value的别名,所以二者任选其一,他们的作用是一样的

  • method 是可以指定可以访问的请求的类型,比如get post 它叶可以写成一个数组的形式。

  • params 可以去指定参数,你还可以去限定这个参数的特征,必须等于某个值,不等于某个值

  • headers 能够影响浏览器的行为

  • consumers 消费者,媒体类型,可以限定必须为application/json;charset=UTF-8

  • produces 产生的响应的类型

关于请求路径的问题

springmvc支持ant风格

  • ? 任意的字符,斜杠例外

  • * 0到n,任意个字符都可以 不能含斜杠

  • ** 支持任意层路径 /m3/** 这样才可以提现出来 /m3** 这样的效果等同于m3后面任意多个字符

@GetMapping 、 @PostMaping.....

  • getMapping 限定了只支持get请求

  • postMapping 限定了只支持post请求

对于非get post请求的支持

对于非get post请求的支持,需要有额外的内容添加,要增加一个过滤器来额外处理

  • 过滤器

  • 返回的不再是页面而是数据

<!--注册一个支持所有http请求类型的过滤器-->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 表单提交里面还要添加一个隐藏的参数

name="_method" value="DELETE"

@Responsebody

返回数据的,一般情况下返回JSON格式,

@ModelAttribute

使用方式一

// 就是在controller里面的任意一个处理具体的方法之前都会执行
@ModelAttribute
public User init(){
    System.out.println("init.......");
    User u = new User();
    u.setName("王菲");
    return  u;
}

@RequestMapping("/login")
public String login(Model model){
    System.out.println(model.containsAttribute("u"));
    System.out.println(model.containsAttribute("user"));
    System.out.println(model.containsAttribute("sdfdsfd"));
    return "msg";
}

如果某些对象从头到尾每次请求当中都要存在,不消失,就适合这么用。

使用方式二

   @ModelAttribute("user")
    public void init(Model model){
        System.out.println("init.......");
        User user = new User();
        user.setName("王菲");
        model.addAttribute("user",user);
    }

如果没有传递这个模型过来,那么方法上加了@modelattribute的为你提供,如果你传了就用你的

@SessionAttribute

@SessionAttributes

这个用在类上面,它会将模型自动填充到会话里面去。

@SessionAttribute

要求当前这次访问当中的会话里面必须要有某个对象

@RequestParam

@RequestBody

json数据,不是通过form表单传递

ajax({

data:

})

@InitBinder

数据转换,将日期转换处理

@PathVariable

restful风格

详情参考并在2000年定义罗伊菲尔丁在他的博士论文。

 

@RestController

Contrller + Response

关于静态资源访问的问题

由于我们的servlet设置了URL匹配方式为/ 所以,它将静态资源也当做一个后台的请求

比如http://localhost:8080/s/static/css/index.css

它尝试去匹配一个static/css/index.css的Controller里面的RequestMapping的组合,因为没有,所以404.

解决方式很多,最简单的,是让springmvc单独处理,将这些交给容器的默认的servlet处理,就不让DispatcherServlet来处理了。

解决方式1

<!--默认的servlet处理者-->
<mvc:default-servlet-handler/>
<!-- 为了,让原有的controller生效,要加一个注解驱动 -->
 <mvc:annotation-driven/>

MIME 类型

解决方式2

通过映射关系描述,一一对编写规则

<mvc:resources mapping="/static/css/*" location="static/css/"/>

解决方式3

自行在web.xml定义映射规则

关于post请求中文乱码问题解决

我们添加一个过滤器即可,springmvc提供了非常好的字符编码过滤器,所以我们注册即可。

<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>
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
​

关于form表单提交数据的方式

方式一 通过属性名字绑定

通过属性名称进行绑定,可以完成数据传递.

页面当中表单元素的name值要和后台的形参的名字保持一致。

如果有多个,多个形参按名字绑定即可,当传入的值较多的时候。

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/8/31
  Time: 8:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${ctx}/user/put" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="text" name="name"><br>
    <input type="password" name="password"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>
​
package com.sz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {


    @PutMapping("/put")
    // 需要额外的json包的支持
    @ResponseBody
    public String  put(String name,String password){
        System.out.println(name+password);
//        Map<String,String> map = new HashMap<>();
//        map.put("msg","ok");
        return "ok";
    }
    

}

方式二 利用@RequetParam

jsp页面不变

后台

@PutMapping("/put")
// 需要额外的json包的支持
@ResponseBody
public String  put(@RequestParam("name") String name, @RequestParam("password") String password){
    System.out.println(name+password);
    //        Map<String,String> map = new HashMap<>();
    //        map.put("msg","ok");
    return "ok";
}

方式三 直接使用pojo形式传递

jsp不变

后台

@PutMapping("/put")
// 需要额外的json包的支持
@ResponseBody
public String  put(User user){
    System.out.println(user.getName() + user.getPassword());

    return "ok";
}

关于form表单提交日期格式数据问题的处理

 处理日期(没有时间)

package com.sz.controller;

import com.sz.pojo.User;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {
//
    @InitBinder("user")
    public void init(WebDataBinder dataBinder){
        // 这里指定什么格式,前台就只能传什么格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setLenient(false);
        dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
    }


    @PostMapping("/put")
    // 需要额外的json包的支持
    @ResponseBody
    public String  put(@ModelAttribute("user") User user){
        System.out.println(user.getName() + user.getPassword());
        System.out.println(user.getBirth());
        return "ok";
    }


}
// 通过initBinder指定了user名字和modelAttribute里面user绑定

不指定名字,根据数据类型一样可以分析解析转换成功

package com.sz.controller;

import com.sz.pojo.User;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {
//
    @InitBinder
    public void init(WebDataBinder dataBinder){
        // 这里指定什么格式,前台就只能传什么格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setLenient(false);
        dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
    }


    @PostMapping("/put")
    // 需要额外的json包的支持
    @ResponseBody
    public String  put(@ModelAttribute User user){
        System.out.println(user.getName() + user.getPassword());
        System.out.println(user.getBirth());
        return "ok";
    }


}

时间+日期

package com.sz.controller;

import com.sz.pojo.User;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {
//
    @InitBinder
    public void init(WebDataBinder dataBinder){
        // 这里指定什么格式,前台就只能传什么格式
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setLenient(false);
        dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
    }


    @PostMapping("/put")
    // 需要额外的json包的支持
    @ResponseBody
    public String  put(@ModelAttribute User user){
        System.out.println(user.getName() + user.getPassword());
        System.out.println(user.getBirth());
        return "ok";
    }


}

在属性上面添加额外的注解


//    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birth;

 

json数据交互

额外依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.3</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.3</version>
</dependency>

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>


<!--添加处理json为javabean-->
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.2</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.2</version>
</dependency>
<!--添加处理json为javabean ==end===-->
另外记得添加
<!--激活springmvc消息转换功能-->
<mvc:annotation-driven></mvc:annotation-driven>
 

JSON数据返回前台以及如何解析

JSON后台返回

返回POJO


    @RequestMapping("/m1")
    @ResponseBody // 这个注解将知道现在返回的不是视图,它会将这个数据转换为JSON格式。
    public User  m1(){
        User u  = new User();
        u.setPwd("321312");
        u.setName("许晴");
        return u;
    }

返回Map

  @RequestMapping("/m2")
    @ResponseBody
    public Map<String,Object> m2(){
        Map<String,Object> map = new HashMap<>();
        map.put("name","许晴请");
        map.put("age",28);
        return map;
    }

返回数组

@RequestMapping("/m3")
//    @ResponseBody
public User[] m3(){
    User u = new User();
    u.setName("开玩笑");
    u.setPwd("123");
    User u2 = new User();
    u2.setName("不开玩笑");
    u2.setPwd("321");
    return new User[]{u,u2};
}
 
  1. 返回List

@RequestMapping("/m4")
public List<User> m4(){
    List<User> l = new ArrayList<>();
    User u = new User();
    u.setName("开玩笑");
    u.setPwd("123");
    User u2 = new User();
    u2.setName("不开玩笑");
    u2.setPwd("321");
    l.add(u);
    l.add(u2);
    return l;
}

JSON前台如何解析

  1. 解析返回的POJO

$('#b1').click(function () {
    $.ajax({
        url:'${ctx}/json/m1',
        type:'post',
        success:function (data) {
            alert(data.name);
            alert(data.pwd);
        }
    })
})
  1. 解析返回的Map


$('#b2').click(function () {
    $.ajax({
        url:'${ctx}/json/m2',
        type:'post',
        success:function (data) {
            alert(data.name);
            alert(data.age);
        }
    })
})
  1. 解析返回的数组

$('#b3').click(function () {
    $.ajax({
        url:'${ctx}/json/m3',
        type:'post',
        success:function (data) {
            for(var i = 0 ; i < data.length; i ++){
                alert(data[i].name);
                alert(data[i].pwd);
            }
        }
    })
})
  1. 解析返回的List

$('#b4').click(function () {
    $.ajax({
        url:'${ctx}/json/m4',
        type:'post',
        success:function (data) {
            for(var i = 0 ; i < data.length; i ++){
                alert(data[i].name);
                alert(data[i].pwd);
            }
        }
    })
})
  1. 返回List<Map<String,User>>

$('#b5').click(function () {
            $.ajax({
                url:'${ctx}/json/m5',
                type:'post',
                success:function (data) {
                    for(var i = 0 ; i < data.length; i ++){
                        alert(data[i].u1.name);
                        alert(data[i].u1.pwd);
                        alert(data[i].u2.name);
                        alert(data[i].u2.pwd);
                    }
                }
            })
        })

JSON数据如何使用Ajax提交到后台,后台如何解析

什么是 AJAX ?

AJAX = 异步 JavaScript 和 XML。

AJAX 是一种用于创建快速动态网页的技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

$.AJAX()基本参数

 url       默认值: 当前页地址。发送请求的地址。

 contentType 主要设置你发送给服务器的格式,dataType设置你收到服务器数据的格式。

 success   请求成功后的回调函数。

 type         默认值: "GET")。请求方式 ("POST" 或 "GET"), 默认为 "GET"。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。

data     发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。禁止此自动转换。必须为 Key/Value 格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。

ajax 的复杂JSON数据,用 JSON.stringify序列化后,然后发送,在服务器端接到然后用 JSON.parse 进行还原就行了,这样就能处理复杂的对象了。

contentType:"application/json;charset=utf-8"

1 前台写法

$('#b1').click(function () {
    //
    var obj = {
        'name':'叶问',
        'pwd':'怕老婆'
    };
​
    $.ajax({
        url:'${ctx}/json2/add',
        type:'post',
        contentType:'application/json',
        data:JSON.stringify(obj),
        success:function (data) {
​
        }
    })
})

2 后台的写法

@RequestMapping("/add")
// User user入参只能处理表单提交的数据
public String add(@RequestBody  User user){
    System.out.println(user.getName() +user.getPwd());
    return "msg";
}
一定要记得添加@requestBody否则无法解析。

关于Form提交数据与Ajax自定义JSON数据提交的区别

form提交方式请求分析截图:

通过ajax组装的json数据发送分析

所以二者发送组装数据的区域存在不同,所以处理方式也不同。

对于form表单提交数据它的contentType是属于Content-Type: application/x-www-form-urlencoded

对于ajax发送JSON则是 application/json.

  1. 发送一个POJO

前台

 
$('#b1').click(function () {
    //
    var obj = {
        'name':'叶问',
        'pwd':'怕老婆'
    };
​
    $.ajax({
        url:'${ctx}/json2/add',
        type:'post',
        contentType:'application/json',
        data:JSON.stringify(obj),
        success:function (data) {
​
        }
    })
})

后台

// 前台如何提交一个User对象过来
@RequestMapping("/add")
// User user入参只能处理表单提交的数据
@ResponseBody
public String add(@RequestBody User user  ){
    System.out.println(user.getName() +user.getPwd());
    return "msg";
}
​
  1. 发送一组POJO到后台

前台

$('#b2').click(function () {
    //
    var obj = {
        'name':'叶问',
        'pwd':'怕老婆'
    };
    var obj2 ={
        'name':'未知名的小帅哥',
        'pwd':'123123'
    };
    var arr = new Array();
    arr.push(obj);
    arr.push(obj2);
​
​
    $.ajax({
        url:'${ctx}/json2/addList',
        type:'post',
        contentType:'application/json',
        data:JSON.stringify(arr),
        success:function (data) {
            if(data.code == 2000){
                alert("陈工啦");
            }
        }
    })
})
​

后台

​
@RequestMapping("/addList")
// User user入参只能处理表单提交的数据
@ResponseBody
public Map<String,Integer> addList(@RequestBody List<User> list  ){
    // ma
    Map<String,Integer> map = new HashMap<>();
    System.out.println(list);
    map.put("code",2000);
    return map;
}
​

XML数据交互

对于很多第三方开发,还是由很多会采用XML作为数据交互,比如微信

1 添加依赖

​
<!--XML数据处理-->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.3</version>
</dependency>
​

2 方法返回数据类型定义

// 描述生产的类型,返回类型的描述,返回什么数据
@RequestMapping(value = "/m1",produces = {MediaType.APPLICATION_XML_VALUE} )
@ResponseBody
public User m1(){
    // 将数据转换为XML形式user
    User u = new User();
    u.setName("张福新");
    u.setPwd("好好学习,记得看书");
    return u;
}
持续更新中。。

猜你喜欢

转载自blog.csdn.net/qq_37939251/article/details/82253960