CORS
CORS:Cross-Origin-Resource-Sharing,是一种现代浏览器普遍支持的跨域解决方案。
具体工作流程:
浏览器在检测到你发送的AJAX请求不是同源请求时,会自动在http请求头添加一个origin字段。
请求是可以发送出去的,我们拿不到数据是因为浏览器在中间做了一层劫持。
获取不到数据的原因:
- 这是一次跨域请求
- 请求确实发送到服务器了
- 服务器也把数据返回到了浏览器
- 但是服务器返回的响应头中,没有告诉浏览器哪些域名可以访问这些数据,也就是Access-Control-Allow-Origin
- 于是浏览器就把这个数据丢弃了
这时,只需要在服务器的响应头添加这个字段即可。
Access-Control-Allow-Origin:*
原生JSONP跨域请求
查询手机归属地的接口不支持CORS跨域请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
document.getElementById('btn').onclick=function(){
const xhr = new XMLHttpRequest();
xhr.open('GET','https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13259141515',true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
}
}
</script>
</body>
</html>
利用JSONP的方式支持跨域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- JSONP请求的原理:利用某些标签不受浏览器同源策略的限制,比如<script><img><link>标签。 -->
<button>JSONP请求非同源数据</button>
<script>
function getJsonDataByJsonp(data){
for(var i in data) {
console.log(i, data[i]);
}
}
document.getElementsByTagName('button')[0].onclick=function(){
var ele = document.createElement('script');
ele.src = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13259141515&callback=getJsonDataByJsonp";
document.body.appendChild(ele);
}
</script>
</body>
</html>
Console
jQuery方式的JSONP跨域请求
JSONP的方式只支持GET请求,不支持POST请求。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>JSONP请求非同源数据</button>
<script src="js/jquery-3.5.1.js"></script>
<script>
$('button').eq(0).on('click',function(){
$.ajax({
type:'GET',
url:'https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13259141515',
success:function(data) {
for (i in data) {
console.log(i, data[i]);
}
},
jsonp:'callback',
dataType:'jsonp'
})
});
</script>
</body>
</html>
jackson
Java对象转JSON字符串
jackson工具类,完成Java对象和JSON字符串的转换。SpringMVC内置的JSON转换工具。
使用场景:JDBC读取数据库数据后,封装为JAVA对象,将对象转换为JSON字符串返回给前台。
CPU类:
package org.westos;
/**
* @author lwj
* @date 2020/7/30 10:37
*/
public class CPU {
private String company;
private String cpuName;
public CPU() {
}
public CPU(String company, String cpuName) {
this.company = company;
this.cpuName = cpuName;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCpuName() {
return cpuName;
}
public void setCpuName(String cpuName) {
this.cpuName = cpuName;
}
}
Phone类:
package org.westos;
/**
* @author lwj
* @date 2020/7/30 10:35
*/
public class Phone {
private String brand;
private String color;
private Double price;
private CPU cpu;
public Phone() {
}
public Phone(String brand, String color, Double price, CPU cpu) {
this.brand = brand;
this.color = color;
this.price = price;
this.cpu = cpu;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public CPU getCpu() {
return cpu;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
}
一定要提供getter/setter方法。
package org.westos;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.HashMap;
/**
* @author lwj
* @date 2020/7/30 10:38
*/
public class MyTest {
public static void main(String[] args) throws JsonProcessingException {
Phone phone1 = new Phone("MI", "钛银黑", 3999.0, new CPU("高通", "高通865"));
Phone phone2 = new Phone("Apple", "白色", 5400.0, new CPU("Apple", "A13"));
ObjectMapper mapper = new ObjectMapper();
String phone1Str = mapper.writeValueAsString(phone1);
System.out.println(phone1Str);
// {"brand":"MI","color":"钛银黑","price":3999.0,"cpu":{"company":"高通","cpuName":"高通865"}}
ArrayList<Phone> phones = new ArrayList<>();
phones.add(phone1);
phones.add(phone2);
String phoneListStr = mapper.writeValueAsString(phones);
System.out.println(phoneListStr);
// [{"brand":"MI","color":"钛银黑","price":3999.0,"cpu":{"company":"高通","cpuName":"高通865"}},{"brand":"Apple","color":"白色","price":5400.0,"cpu":{"company":"Apple","cpuName":"A13"}}]
HashMap<String, Phone> hashMap = new HashMap<>();
hashMap.put("小米10", phone1);
hashMap.put("Apple 11", phone2);
String phoneMapStr = mapper.writeValueAsString(hashMap);
System.out.println(phoneMapStr);
// {"Apple 11":{"brand":"Apple","color":"白色","price":5400.0,"cpu":{"company":"Apple","cpuName":"A13"}},"小米10":{"brand":"MI","color":"钛银黑","price":3999.0,"cpu":{"company":"高通","cpuName":"高通865"}}}
}
}
除了转换为字符串之外,还可以将json字符串存储到文件。
package org.westos;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
/**
* @author lwj
* @date 2020/7/30 10:56
*/
public class MyTest2 {
public static void main(String[] args) throws IOException {
Phone phone1 = new Phone("华为", "亮黑色", 4488.0, new CPU("麒麟", "麒麟9905G"));
Phone phone2 = new Phone("三星", "遐想灰", 6999.0, new CPU("高通", "骁龙865"));
LinkedList<Phone> phones = new LinkedList<>();
phones.add(phone1);
phones.add(phone2);
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new FileWriter(new File("phones.json")), phones);
}
}
[{"brand":"华为","color":"亮黑色","price":4488.0,"cpu":{"company":"麒麟","cpuName":"麒麟9905G"}},{"brand":"三星","color":"遐想灰","price":6999.0,"cpu":{"company":"高通","cpuName":"骁龙865"}}]
注解
package org.westos;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Date;
/**
* @author lwj
* @date 2020/7/30 10:35
*/
public class Phone {
private String brand;
private String color;
private Double price;
@JsonIgnore
private CPU cpu;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date releaseTime;
// 现在只导入了3个包,还不能支持jdk1.8新的时间日期类格式的转换
public Phone() {
}
public Phone(String brand, String color, Double price, CPU cpu) {
this.brand = brand;
this.color = color;
this.price = price;
this.cpu = cpu;
}
public Phone(String brand, String color, Double price, CPU cpu, Date releaseTime) {
this.brand = brand;
this.color = color;
this.price = price;
this.cpu = cpu;
this.releaseTime = releaseTime;
}
public Date getReleaseTime() {
return releaseTime;
}
public void setReleaseTime(Date releaseTime) {
this.releaseTime = releaseTime;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public CPU getCpu() {
return cpu;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
}
@JsonIgnore:该属性不参与转换
@JsonFormat:格式化日期
package org.westos;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;
/**
* @author lwj
* @date 2020/7/30 11:08
*/
public class MyTest3 {
public static void main(String[] args) throws JsonProcessingException {
Phone phone = new Phone("小米", "星空蓝", 4999.0,
new CPU("高通", "骁龙865"), new Date());
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(phone);
System.out.println(str);
// {"brand":"小米","color":"星空蓝","price":4999.0,"releaseTime":"2020-07-30 11:21:49"}
}
}
JSON的值不支持日期类型,可以转换为字符串保存。
JSON字符串转Java对象
利用:GsonFormat插件 下载地址
package org.westos.demo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author lwj
* @date 2020/7/30 11:55
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class Phone {
/**
* brand : 华为
* color : 亮黑色
* price : 4488
* cpu : {"company":"麒麟","cpuName":"麒麟9905G"}
*/
private String brand;
private String color;
private int price;
private CpuBean cpu;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public CpuBean getCpu() {
return cpu;
}
public void setCpu(CpuBean cpu) {
this.cpu = cpu;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class CpuBean {
/**
* company : 麒麟
* cpuName : 麒麟9905G
*/
private String company;
private String cpuName;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCpuName() {
return cpuName;
}
public void setCpuName(String cpuName) {
this.cpuName = cpuName;
}
}
// 新建一个Phone类,属性方法由GsonFormat插件根据JSON字符串自动生成
// 鼠标右键,Generate,选择GsonFormat
}
package org.westos.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* @author lwj
* @date 2020/7/30 11:51
*/
public class MyTest {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String jsonStr = "{\"brand\":\"华为\",\"color\":\"亮黑色\",\"price\":4488.0,\"cpu\":{\"company\":\"麒麟\",\"cpuName\":\"麒麟9905G\"}}";
Phone phone = mapper.readValue(jsonStr, Phone.class);
System.out.println(phone.getBrand());
// 华为
System.out.println(phone.getColor());
// 亮黑色
System.out.println(phone.getPrice());
// 4488
System.out.println(phone.getCpu().getCompany());
// 麒麟
System.out.println(phone.getCpu().getCpuName());
// 麒麟9905G
}
}