JSON:JavaScript Object Notation,是一种轻量级的数据交换格式,易于人阅读编写,也便于机器解析和生成。
很多语言都提供了对json的支持,使得成为了理想的数据交换格式。
轻量级指的是跟xml做比较。
数据交换指的是客户端和服务器之间业务数据的传递格式
语法:json由键值对构成,由花括号包围,每个键由引号引起来,键和值使用冒号分隔,多组使用逗号分割。
<script type="text/javascript">
var jsonObj = {
"key1":12,
"key2":"abc",
"key3":true,
"key4":[11,"arr",false],
"key5":{ // 这个value是一个json。甚至可以是一个json数组,即[{},{}]
"key5_1":551
}
};
alart(jsonObj); // 输出Object,json本身就是个对象,key当作属性
// 访问
alert(jsonObj.key2);
alert(jsonObj.key4[1]);
alert(jsonObj.key5.key5_1);
</script>
先导入关于Json的JAR包,例如:谷歌的 gson-2.2.4.jar
例如有个JavaBean,即Person由两个属性id,name。constructor/get/set/toString都有
public static void test01() {
Gson gson = new Gson();
// JavaBean -> Json
Person person = new Person(1, "苏瞳");
String personJsonStr = gson.toJson(person); // Java对象转化为Json字符串
System.out.println(personJsonStr); // {"id":1,"name":"苏瞳"}
// Json -> JavaBean
// 把Json字符串转化为Java对象(第一个参数是字符串,第二个是要转化回去的Java类字节码对象)
Person p1 = gson.fromJson(personJsonStr, Person.class);
System.out.println(p1); // Person{id=1, name='苏瞳'}
}
public static void test02() {
Gson gson = new Gson();
// List -> Json
List<Person> personList = new ArrayList<>();
personList.add(new Person(2, "哈哈"));
personList.add(new Person(3, "嘿嘿"));
String personListJsonStr = gson.toJson(personList); // toJson可以接受任何类型的参数-Object
System.out.println(personListJsonStr); // [{"id":2,"name":"哈哈"},{"id":3,"name":"嘿嘿"}]
// Json -> List
// 转化为集合就不能简单的转让集合的字节码类了,要使用谷歌提供关于反射的类-TypeToken<T>
List<Person> list = gson.fromJson(personListJsonStr, new PersonListType().getType());
System.out.println(list); // [Person{id=2, name='哈哈'}, Person{id=3, name='嘿嘿'}]
}
Josn -> List 要先自己写一个类PersonListType
,继承 com.google.gson.reflect.TypeToken (或者使用匿名内部类)
public class PersonListType extends TypeToken<List<Person>> { } //泛型写成ArrayList<Person> 也行
public static void test03() {
Gson gson = new Gson();
// Map -> Json
Map<Integer, Person> personMap = new HashMap<>();
personMap.put(4, new Person(4, "嘻嘻"));
personMap.put(5, new Person(5, "哇哇"));
String personMapJsonStr = gson.toJson(personMap);
System.out.println(personMapJsonStr); // {"4":{"id":4,"name":"嘻嘻"},"5":{"id":5,"name":"哇哇"}}
// Json -> Map
Map<Integer, Person> map = gson.fromJson(personMapJsonStr, new PersonMapType().getType());
System.out.println(map); // {4=Person{id=4, name='嘻嘻'}, 5=Person{id=5, name='哇哇'}}
}
Josn -> Map 要先自己写一个类PersonMapType
,继承 com.google.gson.reflect.TypeToken (或者使用匿名内部类)
public class PersonMapType extends TypeToken<Map<Integer, Person>> { } // 里面不用干什么
public static void test04() {
Map<Integer, Person> map = gson.fromJson(personMapJsonStr,
new TypeToken<Map<Integer, Person>>(){}.getType());
System.out.println(map); // {4=Person{id=4, name='嘻嘻'}, 5=Person{id=5, name='哇哇'}}
}
AJAX:Asyncharonous JavaScript And XML,即异步的JS和XML,是指一种创建交互式网页应用的网页开发技术。
是一种浏览器通过JS异步发起请求。局部更新页面的技术。
ajax.html 客户端页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script type="text/javascript">
// 这里使用JS发起Ajax请求,访问服务器AjaxServlet中javaScriptAjax方法,并显示回传的数据
function ajaxRequest() {
// 1. 创建XMLRequest对象
var xmlHttpRequest = new XMLHttpRequest();
// 2.通过open方法设置请求参数。分别是 请求方式,请求地址,是否为异步
xmlHttpRequest.open("GET",
"http://localhost:8080/dynamicobject/ajaxServlet?action=javaScriptAjax",
true);
// 4. xmlHttpRequest对象有个 readyState属性(值有0,1,2,3,4。4代表请求已完成且响应以就绪),
// 每次改变就触发onreadystatechange事件,还有个status属性,值为200,404等,
// 当 readyState == 4 && status == 200 时表示响应已就绪,可以获得后端响应的Json字符串了,
// onreadystatechange事件要在send发送请求之前注册!!
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
// Json字符串变为Json对象,把响应的数据显示在页面的div里面
var JsonObj = JSON.parse(xmlHttpRequest.responseText);
document.getElementById("div01").innerHTML =
"编号:" + JsonObj.id + "<br/> 姓名:" + JsonObj.name;
}
};
// 3.调用send发送请求给服务器
xmlHttpRequest.send();
}
</script>
<body>
<button onclick="ajaxRequest()">ajax request</button>
<div id="div01"></div>
</body>
</html>
AjaxServlet.java 服务器端:
// 自己写dBaseServlet只是利用反射,根据action请求参数值调用Servlet中对应的方法
public class AjaxServlet extends BaseServlet {
public void javaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=utf-8");
System.out.println("Ajax请求过来了");
// 如果服务器这边需要响应一个Person对象。
// 只是把Person对象的引用发送过去是不行的,因为客户端不要对象的地址,而是对象的数据,需要转化为Json格式字符串
Person person = new Person(1, "苏瞳");
Gson gson = new Gson();
String personJsonStr = gson.toJson(person);
resp.getWriter().write(personJsonStr); // 响应流输出就行
}
}
是一种浏览器通过JS异步发起请求。局部更新页面的技术。
局部更新:浏览器地址栏不会发生变化,不会舍去原来页面的内容(上面的使用,只是改了div01里面的内容)
而原来的我们使用a标签请求,浏览器地址栏会发生变法,而且原来的内容也没了,只显示了我们回传的数据。
<a href="http://localhost:8080/dynamicobject/ajaxServlet?action=javaScriptAjax">非Ajax请求</a>
http://localhost:8080/dynamicobject/ajax.html
-> http://localhost:8080/dynamicobject/ajaxServlet?action=javaScriptAjax
同步:发生Ajax请求,页面会等待服务器响应完,才输出响应的数据(执行onreadystatechange事件)和继续执行下面的代码
异步:页面不用等待服务器响应完,就会执行下面的代码(下面的代码值的是onreadystatechange事件下面的代码),什么时候响应完了什么时候输出响应的数据(onreadystatechange事件)。
异步会让用户体验好一点。如果同步的话有多个按钮都执行ajaxRequest(),则点击一下整个页面就会卡住,其他的按钮也不能点了
常用方法:
1.$.ajax()
方法
返回值: XMLHttpRequest
常用参数:
url
:请求的地址
type
:请求的类型,get/post
data
:发送给服务器的数据,两种格式 name=value&name=value 或者 {key:value}
success
:请求成功后的回调函数 ,和原生的onreadystatechange
事件差不多
dataType
:预期响应的数据类型(预期服务器返回的数据类型),常用有text(纯文本),xml(xml数据),json(json数据/对象)
dataType,如果是text的话需要在success后面的回调函数里使用JSON.parse(str)转化为json对象,是json的话就不同了直接可以使用。
$("#btn01").click(function () {
$.ajax({
url:"http://localhost:8080/dynamicobject/ajaxServlet",
data:"action=jQueryAjax",
type:"GET",
success:function (data) { // 参数就是服务器返回的数据
$("#div02").html("编号:" + data.id + "<br/> 姓名:" + data.name);
},
dataType:"json"
});
});
2.$.get()
简单的GET请求功能,底层封装的复杂的$.ajax()
, $.post()一样的
参数:url
,data
发送的数据(参数),callback
成功的回调函数,type
返回的数据格式
// 按照上面参数的顺序传进去了
$("#btn01").click(function () {
$.get("http://localhost:8080/dynamicobject/ajaxServlet", "action=jQueryAjax", function (data) {
$("#div02").html("编号:" + data.id + "<br/> 姓名:" + data.name);
}, "json");
}
3.$.getJSON()
GET 请求载入 JSON 数据,即请求方式是GET,返回的类型统一是Json
参数:url
,data
,callback
// 按照上面参数的顺序传进去了
$.getJSON("http://localhost:8080/dynamicobject/ajaxServlet", "action=jQueryAjax", function (data) {
$("#div02").html("编号:" + data.id + "<br/> 姓名:" + data.name);
});
4.serialize()
表单序列化 ,即可以把表单项中所有的内容都获取到,并以name=value&name=value的形式进行拼接
alert( $("#form01").serialize() );
// username=zgq&password=123
// 可以联合上面的使用
$.getJSON("http://localhost:8080/dynamicobject/ajaxServlet",
"action=jQueryAjax&" + $("#form01").serialize(), // 可以把表单的信息一起提交服务器,不要忘了&
function (data) {
$("#div02").html("编号:" + data.id + "<br/> 姓名:" + data.name);
}
);
Internationalization - 国际化,由于字符过长,简称i18n,i首字母,n尾字母,之间有18的字母,即i18n
需求:不同的国家人访问,看到的内容不同,布局一样
苹果的策略是:为不同的国家创建不同的网站,英文
http://www.apple.com
,中文http://www.apple.com/cn
如果需求不大可用采用苹果这种策略
类路径下有两个文件:i18n_en_US.properties 文件,i18n_zh_CN.properties 文件
# i18n_en_US.properties register=register username=username password=password submit=submit # i18n_zh_CN.properties register=注册 username=用户名 password=密码 submit=提交
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
后端代码:
public class Test {
public static void main(String[] args) {
Locale aDefault = Locale.getDefault(); // zh_CN (系统默认的Locale对象)
Locale china = Locale.CHINA; // 获取中国的Locale对象 zh_CN
Locale us = Locale.US; // 美国 en_US
// properties文件命名规则:baseName_locale.properties,
// 如果多个文件都这样命名的话idea会以baseName命名创建一个文件夹
ResourceBundle bundle = ResourceBundle.getBundle("i18n", china);
String username = bundle.getString("username"); // 他会根据时区去加载对应的properties文件
System.out.println(username);
}
}
<!-- i18n_test.jsp文件-->
<body>
<%
Locale locale = request.getLocale(); // 根据请求头获取客户的语言信息
ResourceBundle bundle = ResourceBundle.getBundle("i18n", locale); // 绑定资源下面用jsp脚本输出
%>
<h1><%= bundle.getString("register") %></h1>
<form>
<tr>
<td><%= bundle.getString("username") %></td>
<td><input name="username" type="text" /></td>
</tr>
<tr>
<td><%= bundle.getString("password") %></td>
<td><input name="password" type="password" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="<%= bundle.getString("submit") %>" />
</td>
</tr>
</form>
</body>
<!-- i18n_test.jsp文件-->
<body>
<%
Locale locale = null;
String country = request.getParameter("country");
if ("CN".equals(country)) {
locale = Locale.CHINA;
} else if ("USA".equals(country)) {
locale = Locale.US;
} else {
locale = request.getLocale(); // 都不是则按照请求头获取就行了
}
ResourceBundle bundle = ResourceBundle.getBundle("i18n", locale);
%>
<!-- 有些用户不会设置浏览器的语言信息,则可用使用这种按钮绑定时区信息-->
<a href="i18n_test?country=CN">中文</a>| <!-- i18n_test代表还是请求这个页面-->
<a href="i18n_test?country=USA">english</a>
.....下面和上面的一样
</body>
⭐优化使用EL和JSTL,代替JSP的脚本:
<!-- 下面是i18n.jsp文件,使用EL和JSTL,先导入JSTL标签库-->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<body>
<fmt:setLocale value="${param.locale}"/> <!-- 1.设置语言信息,没获取到就用浏览器默认的-->
<fmt:setBundle basename="i18n"/> <!-- 2.设置baseName-->
<!-- <fmt:message key="username"/> 3.输出 -->
<a href="i18n.jsp?locale=zh_CN">中文</a>|
<a href="i18n.jsp?locale=en_US">english</a>
<h1><fmt:message key="register"/></h1>
<form>
<tr>
<td><fmt:message key="username"/></td>
<td><input name="username" type="text" /></td>
</tr>
<tr>
<td><fmt:message key="password"/></td>
<td><input name="password" type="password" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="<fmt:message key="submit"/>" />
</td>
</tr>
</form>
</body>