其他分享
首页 > 其他分享> > Springboot:前后端分离——提交url返回json

Springboot:前后端分离——提交url返回json

作者:互联网

学习自:SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式_java_脚本之家

1、前言

现在大多数互联网项目都是采用前后端分离的开发方式:

在与前端交互的过程中,常用Json数据与前端进行交互。

如果想获取前端送来的Json,需要用@RequestBody注解

该注解用于获取http request的内容(字符串),通过SpringMVC提供的HttpMessageConverter接口将读取到的内容转换为Json、xml等格式的数据,并将其绑定到Controller方法的参数上,

提交方式为POST时

 

 

2、注解 

3、请求路径参数:GET

一般用于查询数据,采用明文传输,用于获取用户无关的信息。

可以用@GetMapping注解,它其实是@RequestMapping( method = ReuqestMethod.GET )的缩写。

3.1、GET请求,URL路径传参:用 url?param=value的形式

GET请求通过URL传参,如:

http://localhost:4001/api/unit?code=111

对上文的解释,如果识别到类似URL?Param=Value这种URL,那么Param及其值会被传入@RequestParam标注的各项参数。

 

后端如果要获取这样的URL,可以用@RequestParam注解

@RestController
public class HelloController{
    @RequestMapping(value="/hello",method=RequestMethod.GET)
    public String sayHello(@RequestParam Integer id){
        return "id:"+id;
    }
}

上文中,对于URLhttps://IP:端口/hello?Param=Value这种URL,Value作为@RequestParam变量id的值被传入

 

3.2、GET请求,URL路径参数:用url/value1/value2/...的形式

与3.1相比,省略了参数名

如:http://localhost:4001/api/unit/1

后端如果要获取路径参数1,可以用@PathVariable

@RestController
public class HelloController{
    @RequestMapping(value="/hello/{id}/{name}",method=ReuqestMethod.GET)
    public String sayHello(@PathVariable("id") Integer id,@PathVariable("name") String name){
        return "id:"+id+" name:"+name;
    }
}

上文中,对于URLhttps://IP:端口/hello/Value1/Value2这种URL,Value1作为@RequestParam变量id的值,Value2作为@RequestParam变量name的值被传入。

 

3.3、小结

路径传参:URL为URL?Param=Value,用@RequestMapping(value=URL) + @RequestParam 类型 变量名提取参数值

路径参数:URL为url/value1/value2/...,用@RequestMapping(value="url/{param1}/{param2}/...") + @PathVariable("param") 类型 变量名提取参数值

4、Body参数与POST请求

4.1、POST请求,Body传值

推荐使用JSON格式传值,在postman中设置如下

 

 

后端接收这种数据要用@RequestBody@RequestParam注解:

//用map接收
@PostMapping(path = "/demo1")
public void demo1(@RequestBody Map<String,String> person){
     System.out.println(person.get("name"));
}

//或者用Entity类对象接收
@PostMapping(path = "/demo1")
public void demo1(@RequestBody Person person){
    System.out.println(person.toString())
}

注意

@RequestBody是用来处理前台发来数据Content-Type,而application/x-www-form-urlencoded编码的内容,例如application/json、application/xml等

使用@RequestBody注解接收参数时,从名称上来看也就是说要读取的数据放在请求体中,前台请求的JSON数据的Content-Type必须为application/json,否则会类型不支持的异常错误“org.springframework.web.HttpMediaTypeNotSupportedException”

当Ajax用application/x-www-form-urlencoded格式上传数据时,会使用JSON对象,后台只能用@RequestParamServlet获取参数

当Ajax用application/json格式上传数据时,会使用JSON字符串,后台可以用@RequestBody@RequestParam获取参数。

 

 

如何定义后台接收参数,使之可以与前台发来的JSON数据对应呢?

若是JSON中的KeyEntity类中可以找到对应的Field,就会自动映射,即前台传来的JSON的Key必须在Entity中存在,且同名,不然就会报错。

 

4.2、POST请求,Headers、Cookie传值

 

 

 这里我们把Content-Type设置为JSON格式。

我们还可以在Headers中加入别的参数,比如Token

后端可以通过HttpServletRequest获取请求头的内容,如:

//三个方法
request.getHeader(string name)方法:String 
request.getHeaders(String name)方法:Enumeration 
request.getHeaderNames()方法
 
@GetMapping("/demo3")
public void demo3(HttpServletRequest request) {
    System.out.println(request.getHeader("myHeader"));
    for (Cookie cookie : request.getCookies()) {
        if ("myCookie".equals(cookie.getName())) {
            System.out.println(cookie.getValue());
        }
    }
}

 

 

5、HttpServletRequest

前端JS发送Ajax请求,Content-Type发送信息至服务器内部的编码类型,默认为application/x-www-form-urlencoded,这种格式的特点是name/value为一组,每组间用&连接,这种形式是没有办法将复杂Json组织成Key-Value的形式。

data_type设置为收到的服务器数据的格式,不指定时自动判断:

  var jsonObj = {"openid":"xxx","username":"Ed sheeran","password":"123"};
          /*
              Jquery默认Content-Type为application/x-www-form-urlencoded类型
           */
          $.ajax({
              type: 'POST',
              url: "/login",
              dataType: "json",
              data: JSON.stringify(jsonObj),
              success: function(data) {
                  console.log(data)
              },
              error: function() {
                  console.log("fucking error")
              }
          });

后端Servlet接收参数。如果前端报200,后端也是200返回null

@Controller
public class LoginController {
  @PostMapping("/login")
  public void login(HttpServletRequest request){
      System.err.println(request.getParameter("openid"));
      System.err.println(request.getParameter("username"));
      System.err.println(request.getParameter("password"));
}

后端用@RequestBody接收参数,前端报415,后端报Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported Http status 415 Unsupported Media Type

@Controller
public class LoginController {
  @PostMapping("/login")
  public void login(@RequestBody Map<String,Object> map){
      System.err.println(map.get("username"));
      System.err.println(map.get("password"));
      System.err.println(map.get("openid"));
  }

如果在前端Content-Type:“application/json”

var jsonObj = {"openid":"xxx","username":"Ed sheeran","password":"123"};
$.ajax({
              type: 'POST',
              url: "/login",
              dataType: "json",
              data: JSON.stringify(jsonObj),
              contentType : "application/json",
              success: function(data) {
                  console.log(data)
              },
              error: function() {
                  console.log("fucking error")
              }
          });

后端用@RequestBody + Map接收,前端200,后端仍能接收参数::

@Controller
public class LoginController {
  @PostMapping("/login")
  public void login(@RequestBody Map<String,Object> map){
      System.err.println(map.get("username"));
      System.err.println(map.get("password"));
      System.err.println(map.get("openid"));
}
}

后端用@RequestBody + Entity对象来接收时。前端报200,后端也是OK:

public class LoginController {
  @PostMapping("/login")
  public void login(@RequestBody Form form){
      System.err.println(form);
}
}
public class Form {
  private String openid;
  private String username;
  private String password;
 
  // get set
 
  @Override
  public String toString() {
      return "Form{" +
              "openid='" + openid + '\'' +
              ", username='" + username + '\'' +
              ", password='" + password + '\'' +
              '}';
  }
}

6、参数校验

后端接收到前端数据,如果要对前端数据进行校验,可以加入SpringBootValidate依赖

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
</dependency>

使用时,只需要在接收数据的Entity前@Valid注解,用BindingResult接收错误、不合法的提示信息

public R hh(@RequestBody @Valid Users user , BindingResult result){
    ...
}

 

 

接收参数的Entity类的对应Field前还要加校验注解,比如@NotEmpty(message="密码不能为空")

 

 

还可以用正则表达式的方式来对属性进行校验,只需要加上如下注解:

@Pattern(
        regexp =  正则表达式,
        message = "输入格式不合法"
)

2、当后端接收完前端JSON,响应也是返回JSON给前端,此时只需要在后台Controller类加上@ResponseBody注解即可。

该注解用于将Controller方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据,如JSON、xml等,通过Response响应前端

@Controller + @ResponseBody返回JSON数据前端,还可以用@RestController来替换,使代码更简洁。

下图为返回的JSON数据的前缀注解:

 

 

 

注意:

7、最终选择交互方式

7.1、POST请求

最常用的交互方法为:

前端代码:

    var jsonObj = {"openid":"xxx","username":"Ed sheeran","password":"123"};
          /*
              Jquery默认Content-Type为application/x-www-form-urlencoded类型
           */
          $.ajax({
              type: 'POST',
              url: "/login",
              dataType: "json",
              data: JSON.stringify(jsonObj),
              contentType : "application/json",
              success: function(data) {
                  console.log(data)
              },
              error: function() {
                  console.log("fucking error")
              }
          });

后端代码1,Entity

@Controller
public class LoginController {
  @PostMapping("/login")
  public void login(@RequestBody Form form){
      System.err.println(form);
}
}

后端代码2,Map

@Controller
public class LoginController {
  @PostMapping("/login")
  public void login(@RequestBody Map<String,Object> map){
      System.err.println(map.get("username"));
      System.err.println(map.get("password"));
      System.err.println(map.get("openid"));
}
}

7.2、GET请求

路径参数:用@RequestParam@PathVariable获取路径参数

header传值:用HttpServletRequest获取

POST请求Body传参:如果参数较多,可以用@RequestBody+Map或Entity接收;如果参数不多,可以用@RequestParam单个映射接收。

 

标签:Springboot,url,JSON,System,RequestBody,json,参数,println,public
来源: https://www.cnblogs.com/ShineLeBlog/p/16453976.html