局部请求页面不会变化,返回的响应我们要动态获取,获取后选择数据更新区域。
<body>
<input id="btnLoad" type="button" value="加载">
<div id="divContent"></div>
<script>
//获取点击按钮
document.getElementById("btnLoad").onclick=function (){
var xmlhttp;
//根据不同的浏览器,创建xmlhttp的对象
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp=new ActiveXObject("eage.xmlhttp")
}
console.log("xmlhttpRequest", xmlhttp);
//创建一个请求
xmlhttp.open("GET", "/content");
//发送一个请求
xmlhttp.send();
//监听ajax的执行过程
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//获取响应的文本
var t=xmlhttp.responseText;
console.log(t);
console.log(document.getElementById("divContent").innerHTML);
document.getElementById("divContent").innerHTML=document.getElementById("divContent").innerHTML+"<br/>"+t;
}
};
}
</script>
全局请求会更新整个页面例子如下。
<body>
<form action="/request" method="post">
<input name="username"/>
<input name="password" type="password"/>
<input type="submit">
</form>
</body>
@WebServlet("/request")
public class RequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse respose) throws ServletException, IOException {
respose.getWriter().println("get");直接更新了整个页面
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse respose) throws ServletException, IOException {
respose.getWriter().println("post");
}
}
respose.getWriter().println("get");会将原来的页面销毁掉,重新生成另一张页面,但是在原来的页面中有不需要刷新的页面,我们想要的效果只是小部分区域进行显示刷新出来的内容,这时就要用到Ajax。
[
{
"empno": "7369",数字可以加双引号也可以不加
"ename": "李宁",
"job": "软件工程师",
"hiredate": "2015-02-2",
"salary": 1300,
"dname": "研发部"
},
{
"empno": "73691",
"ename": "李上",
"job": "软件工程师",
"hiredate": "2015-02-2",
"salary": 1300,
"dname": "研发部"
}
]
JS如何展示json数据利用json数据如下
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
var employeeList=
[
{
"empno": "7369",
"ename": "李宁",
"job": "软件工程师",
"hiredate": "2015-02-2",
"salary": 1300,
"dname": "研发部"
},
{
"empno": "73691",
"ename": "李上",
"job": "软件工程师",
"hiredate": "2015-02-2",
"salary": 1300,
"dname": "研发部"
}
]
for(var i=0;i<employeeList.length;i++){
var employee=employeeList[i];
console.log(employee);
document.write("<h1>");
document.write(employee.ename);
document.write(employee.empno);
document.write(employee.job);
document.write("</h1>");
}
</script>
</head>
注意:ajax请求返回的不再与展现相关,而是纯纯的数据,浏览器接受后要考虑如何展示。
两个数据转换核心问题:
数据对象序列化为JSON字符串----JacKson解决序列化问题
JSON字符串如何转换成数据对象--
@WebServlet("/news")
public class NewServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<News> list = new ArrayList<>();
list.add(new News("TIOBE:2018编程语言排行趋势","2018","TIBOT","...."));
list.add(new News("TIOBE:2017编程语言排行趋势","2017","TIBOT","...."));
list.add(new News("TIOBE:2016编程语言排行趋势","2016","TIBOT","...."));
//序列化过程,可能报错
ObjectMapper objectMapper=new ObjectMapper();
String json = objectMapper.writeValueAsString(list);
response.setContentType("text/json;charset=utf-8");
response.getWriter().println(json);
}
}
Tomcat配置问题:Warning:The selected directory is not a TomEE home
解决:tomcat选择的时候选错了
错误: 代理抛出异常错误: java.rmi.server.ExportException: Port already in use: 1099; nested exception is:
java.net.BindException: Address already in use: JVM_Bind
解决:端口占用了
解决:中途导入的jar包和依赖没有被out出来,最后允许的目录在Out,如果jar添加了,out没有,那么此时需要手动添加
反序列化过程:
<body>
<div id="container"></div>
<script>
//开始纯手工处理ajax
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}else {
xmlhttp=new ActiveXObject("XMLHTTP");
}
xmlhttp.open("GET","/news");
xmlhttp.send();
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState==4&&xmlhttp.status==200){
var str=xmlhttp.responseText;
//JSON.parse()方法,把字符串编程json的对象
console.log(JSON.parse(str));
//渲染页面(二次加工数据)
for (var i = 0; i < json.length; i++) {
var news=json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}
};
</script>
</body>
原生的ajax要创建对象,接受并且判断响应,很麻烦,有封装好的。
get方式发送请求:
<body>
<div id="container"></div>
<script>
// 第一个参数是对应的url是什么,,第二个向服务器传递的参数
//axios.get('/news?t=pypl').then。。的传参方式也可
axios.get('/news',{params:{"t":"pypl"}}).then(function (response) {
console.log(response);
var json=response.data;
for (var i = 0; i < json.length; i++) {
var news=json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}).catch(function (error) {
console.log(error);
});
</script>
</body>
post方式发送请求:
<script>
//写法一
//"t=pypl&1=abc连续的参数用&隔开
//{headers:{"content-type":"application/x-www-form-urlencoded"}}手动定义请求头固定写法
// axios.post("/news1","t=pypl&1=abc",
// {headers:{"content-type":"application/x-www-form-urlencoded"}})
//写法二
const params = new URLSearchParams();
params.append("t","pypl");
params.append("l","abc");
axios.post("/news",params)
.then(function (response) {
console.log(response);
var json = response.data;
for (var i = 0; i < json.length; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}).catch(function (error) {
console.log(error);
});
</script>
异步执行代码实例:
<body>
<div id="container"></div>
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}else {
xmlhttp=new ActiveXObject("XMLHTTP");
}
xmlhttp.open("GET","/news?t=pypl");
xmlhttp.send();
console.log("请求已经发送");
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState==4&&xmlhttp.status==200){
var str=xmlhttp.responseText;
//JSON.parse()方法,把字符串编程json的对象
console.log(JSON.parse(str));
//渲染页面(二次加工数据)
for (var i = 0; i < json.length; i++) {
var news=json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}
};
</script>
结果:send没有收到响应,就执行console.log("请求已经发送");这句话,然后随着状态变化事件得到执行。
<body>
<div id="container"></div>
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}else {
xmlhttp=new ActiveXObject("XMLHTTP");
}
xmlhttp.open("GET","/news?t=pypl",false);
xmlhttp.send();
console.log("请求已经发送");
if(xmlhttp.readyState==4&&xmlhttp.status==200){
var str=xmlhttp.responseText;
//JSON.parse()方法,把字符串编程json的对象
console.log(JSON.parse(str));
//渲染页面(二次加工数据)
for (var i = 0; i < json.length; i++) {
var news=json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}
xmlhttp.onreadystatechange = function () {
};
</script>
</body>
结果:当send执行没有结束,没有收到响应,不会执行console.log("请求已经发送");,导致事件状态变化监听失败,所以if必须提前,那么就可以执行相应的语句;
效果
准备数据
@WebServlet("/channel")
public class ChannerServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//levels为一级目录大类,parent为一级大类的code,这两个都是用户选择的参数
//用户根据需要选择一级大类,然后根据用户的选择获取大类的code,再用parent和用户选择的比较,得到二级大类
String level=request.getParameter("level");
String parent = request.getParameter("parent");
List<Channel> chlist = new ArrayList<>();
if (level==null){
level = "0";
} else if (parent==null) {
parent = "0";
}
if (level.equals("1")) {
chlist.add(new Channel("ai","人工智能"));
chlist.add(new Channel("web","前端开发"));
}else if(level.equals("2")){
if (parent.equals("ai")) {
chlist.add(new Channel("dl","深度学习"));
chlist.add(new Channel("cv","计算机视觉"));
chlist.add(new Channel("nlp","自然语言处理"));
} else if (parent.equals("web")) {
chlist.add(new Channel("html","前端html"));
chlist.add(new Channel("css","前端css"));
chlist.add(new Channel("js","前端js"));
}
}
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(chlist);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(json);
}
}
实体类:
public class Channel {
private String code;
private String name;
public Channel(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
前端界面发送请求:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
</head>
<body>
<select id="lv1" style="width: 200px;height: 30px">
<option value="-1" selected="selected">请选择</option>
</select>
<!--//不写option标签,直接往里边添加会直接显示-->
<select id="lv2" style="width: 200px;height: 30px">
</select>
<script>
//获取lv1标签,为了往lv1的option中放数据
var lv1 = document.getElementById("lv1");
axios.get("/channel",{params:{"level":1}})
.then(function (response) {
var json = response.data;
console.log(json);
for (var i=0;i<json.length;i++){
var channel = json[i];
//新创建的option对象,第一个参数是text,第二个是value
// new(text?: string, value?: string,...)
//如果有选择,那么select的value就是option的value
lv1.options.add(new Option(channel.name, channel.code));
}
});
var lv2 = document.getElementById("lv2");
lv1.onchange=function () {
axios.get("/channel",{params:{"level":2,"parent":lv1.value}})
.then(function (response) {
var json = response.data;
//直接把之前的数据清除的办法,length=0就行了
lv2.length=0;
console.log(json);
for (var i=0;i<json.length;i++){
var channel = json[i];
lv2.options.add(new Option(channel.name, channel.code));
}
});
}
</script>
</body>
</html>