初识Json浅扯ajax
1.引入Json
请求地址:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su
2.使用json依赖
2.1.使用fastjson需要的依赖(网上搜罗的)
这个没有提供JSON.toJSONString(Object object);方法,提供了其他一些方法,自行参考:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.3</version>
</dependency>
2.2. 单独使用一个依赖也可以(至于方法自行查看):
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
2.3.第三方阿里提供的fastjson包
这个提供了JSON.toJSONString(Object object);方法
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
新版本点击量较多的依赖:
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
3.Json对象和Js对象的区别:
var obj = {key1: 'Hello', key2: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的;a和b是键,他们冒号后面是对应的值
var json = '{"key1": "Hello", "key2": "World"}'; //这是一个 JSON 字符串,本质是一个字符串,即整个大括号用引号包裹
//1.Json对象转化为js对象
var obj = JSON.parse('{"key1": "Hello", "key2": "World"}');
//结果是 {a: 'Hello', b: 'World'}
//2.js对象转化为Json对象
var json = JSON.stringify({key1: 'Hello', key2: 'World'});
//结果是 '{"a": "Hello", "b": "World"}'
总结:js中对象的key对应java中对象的属性,key后面的值对应java对象中的属性值,而Json在{}外面裹一层单引号,使{}及其里面的东西具备了字符串的含义。
4.Json的应用
@Controller
public class UserController {
@RequestMapping("/json")
@ResponseBody
public String jsonTest() throws JsonProcessingException {
//创建一个jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("白小纯", 20, "男");
//将我们的对象解析成为json格式
String str = mapper.writeValueAsString(user);
//由于@ResponseBody注解,这里会将str转成json格式返回;
return str;
}
}
下本地tomcat启动测试一下,控制台出现乱码采用将 @RequestMapping("/json")
改为
//produces:指定响应体返回类型和编码
@RequestMapping(value = "/json",produces = "application/json;charset=utf-8")
即可。
更为方便的在Web.xml中配置:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
5.在ssm整合中出现前端请求,后端数据库处理成功,但是后端反馈到前端的效果不符预期(后期陆续补充ing~~~):
demo:
$.ajax({
type:"post",
url:"${pageContext.request.contextPath}/product/delete.do",//controller中的请求路径
async:false,
data:{'productList':productList.toString()},//controller返回的数据为data,{'productList':productList.toString()}为json对象
dataType:'json',
success:function (data) {
if(data.result > 0 ){
alert("删除成功")
}
},
error:function () {
alert("删除失败")
document.execCommand('Refresh')
}
})
window.location.reload(true)
}
一般代码执行到请求后台处理:url:"${pageContext.request.contextPath}/product/delete.do",
这段之前都是没问题的。
5.1.只执行error
原因:dataType不写默认为String类型,如果controller返回的是java对象类型或其他非String类型就会出现上述情况。
解决:在controller类对应方法上写上@ResponseBody注解即可。在controller类返回默认走的是视图解析器,写上这个就会自动将返回值转化为json格式返回到前端。
总结:后端返回的数据与dataType指定的数据类型要一致。
5.2.ssm使用layui使用ajax没有执行succes
问题背景:
controller类中相应方法加了@ResponseBody,返回java对象,dataType指定为json;点击提交按钮提交表单不执行succes。
原因:在js函数后面没加return false,导致提交按钮默认提交;更详细地说,用到了layui或者bootstrap框架(layui基于bootstrap框架),bootstrap框架下的form表单中的按钮被点击后会自动刷新页面。
解决:js函数后面加return false或者将form改为div。
5.3.controller类中相应方法返回的字符串中含有特殊符号,如换行符等
需要返回的字符串:
String retJsonStr = "{\"limitEnd\":15,\"limitStart\":0,\"list\":[{\"catalogId\":23,\"costPrice\":123,\"description\":\"<p>\\r\\n 去玩儿去玩儿车</p>\\r\\n\",\"distributorId\":\"PD1000003\",\"externalCatalogId\":100,\"externalCatalogName\":\"日用\",\"goodsId\":43,\"goodsName\":\"测试用1\",\"goodsProperty\":\"001001\",\"goodsPropertyCn\":\"实物\",\"marketPrice\":\"122\",\"parentCatalogId\":1,\"parentCatalogName\":\"家居百货1\",\"payType\":\"01\",\"providerId\":\"P1000045\",\"purePointsPrice\":12,\"salePrice\":43,\"saleRefPrice\":\"\",\"shortenedForm\":\"测1\",\"stableCashPrice\":23,\"stablePointsPrice\":34,\"status\":\"03\",\"stock\":\"9999\"}],\"msg\":\"success!\",\"statusKey\":\"00\",\"totalCount\":1}";
分析:java HttpServletResponse将含有特殊符号的字符串转换成json对象时不识别导致,可以返回test类型。
解决:
- controller中方法加
response.setCharacterEncoding("UTF-8"); response.setContentType("text/plain");
- ajax加
dataType: "text",
5.4.更变态的不进入succes的bug
jsp:
function deleteAll() {
var checkNum=$("input[name='ids']:checked").length;
if(checkNum==0){
alert("请至少选择一项");
return;
}
if(confirm("确定要删除吗?")){
var productList=new Array();
$("input[name='ids']:checked").each(function () {
productList.push($(this).val())
});
}
$.ajax({
type:"post",
url:"${pageContext.request.contextPath}/product/delete.do",//controller中的请求路径
async:false,
data:{productList:productList.toString()},//controller返回的数据为data,{'productList':productList.toString()}为json对象
dataType:'json',
success:function (data) {
if(data.result > 0 ){
alert("删除成功")
}
},
error:function () {
alert("删除失败")
document.execCommand('Refresh')
}
})
window.location.reload(true)
}
controller:
@RequestMapping("/delete.do")
@ResponseBody
public Object deleteProduct(@RequestParam("productList") String productList, Model model){
String[] strs=productList.split(",");
List<String> ids=new ArrayList<>();
for(int i=0;i<strs.length;i++){
ids.add(strs[i]);
}
Map<String, Integer> map=new HashMap<String, Integer>();
boolean isOk = productService.deleteProduct(ids);
if(isOk) {
map.put("result",1);
}else {
map.put("result",0);
}
return JSON.toJSONString(map);
}
}
分析:本来按文中此段后面对同步异步的分析,即使是默认异步等到执行完也会进入succes弹出警示框,但是并没有,因此可以理解为即使dataType正确,data没毛病(因为加了async:false,后一切跟预期一样,也有警示框),使用了异步,执行完向后端发送请求,后端一切处理如预期所想,也不会执行succes,至于原因有以下猜想:网页中使用了其他未知的代码段阻止了这一操作,又或者Web.xml文件或者我ssm项目的其他配置文件做了限制,也有可能是浏览器原因…具体原因有待分析,知道的大佬麻烦解释一下哈。
6.ajax内部返回值获取返回值失败:
6.1.
- 方式:(1)同步调用(2)在ajax函数中return值
- 结果:返回1
- 失败原因:ajax内部是一个或多定义的函数,在ajax内部仅仅返回到ajax内部这个所谓的自定义函数function(data)而不是ajax外层函数test1。
function test1(){
var result = 1;
$.ajax({
url : 'test.do',
type : "post",
data : {},
async : false,//同步
success : function(data) {
return 2;
}
});
return result;
}
6.2.
- 方式:(1)异步调用(2)在ajax对全局变量进行设值(3)ajax函数外将变量return
- 结果:返回 1。未成功获取返回值
- 失败原因:ajax请求和后面的return result语句异步执行,
导致return result比result = 2先执行并返回result的值
function test2(){
var result = 1;
$.ajax({
url : 'test.do',
type : "post",
data : {},
async : true,//异步
success : function(data) {
result = 2;
}
});
return result;
}
6.3.
- 方式:(1)同步调用 (2)且在ajax对全局变量进行设值 (3)ajax函数外将变量return
- 结果:返回 2。成功获取返回值
- 成功原因:先执行result = 2;再往下执行return result;
function test3(){
var result = 1;
$.ajax({
url : 'test.do',
type : "post",
data : {},
async : false,
success : function(data) {
result = 2;
}
});
return result;
}
6.4.ajax异步同步总结:
- async : true设置为异步
- async : false设置为同步
- async默认:true
- 同步的意思是当js代码加载到当前ajax的时候把页面其他代码的加载全部停止,页面出现假死现状态,当这个ajax执行完成后才会继续运行其他页面解除假死状态。而异步在这个ajax代码执行的时候其他代码也可以执行。