javaWeb - 2 — ajax、json — 最后附:后台获取前端中的input type = "file"中的信息 — 更新完毕
1、ajax是什么?
面向百度百科一下就知道了,这里就简单提炼一下
- Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)。当然其实我们学的应该叫:异步JavaScript和ajax
- 包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest
- 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作
用我的话说就是:ajax就是为了异步提交请求,从而只刷新一个局部区域的内容,不影响另外内容的刷新
- 什么意思?很简单,都见过一个场景,当我们在注册账号的时候,我们输入用户名,输入框后面就会提示:该用户重名了,但是不是刷新了整个页面,而是只刷新了这一个用户名的输入框。这是怎么做到的,就是通过ajax异步请求做到的
2、原生的ajax应该怎么玩儿?
对于学java的人来说:简单得要死,就他喵的三部曲
- 获取xmlHttpRequest对象
- 回调监听 onreadystatechange / 获取需要传递的数据
- 向后台发起请求、发送数据( 注:get、post这两种方式的发送数据的方法不太一样,但是道理其实都没变
(1)、那么就来实操一下嘛,先用get方式提交请求
// 1、创建XMLRequest对象( 注意:考虑浏览器的不同 )
var xmlhttp;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 这几种浏览器获取XMLRequest对象的方式
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
// 2、回调监听onreadystatechange
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
// 3、发送数据( 发送get请求 )
xmlhttp.open("GET","/接口名 ? 要传给后台的数据参数"); // 注意这个参数是:key-value的形式传送的
// 多个参数数据使用 & 隔开
xmlhttp.send(); // 发送请求
- (2)、post方式提交
- 其实和get方式是差不多的,只是发送数据哪里做一下修改即可,改成如下方式:
xmlhttp.open("POST","/后端的接口名 ? 要给后台传送的数据参数");
xmlhttp.send();
或者是:
xmlhttp.open("POST","/后台的接口名",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 这是请求头的设置,不会的可以直接百度
xmlhttp.send("fname=Henry&lname=Ford"); // 即:这里面直接跟要发给后台的数据参数
- (3)、后端是怎么获取这个ajax中传递过去的参数的呢?
- 很简单:get和post发给后台的数据不是都是以key-value的形式发过去的吗,那么:在后端直接使用 httpServletRequest对象.getParameter( String key ) 的方式即可获取到get或post中携带的value值。
多提一嘴:后台获取前端的数据,基本上都是通过 httpServletRequest对象.getParameter( String key / name ) 的方式获取的数据。但是:前端中input type = “file”的值不是这么获取的,而是需要在前端中 new一个FormData对象来进行操作。
即:在前端
- 获取file的files属性( 获取file的节点.prop( "files" ) )
- 然后通过 FormData对象.append("file" , files[0]) 的方式把这个file中的信息存到FormData中去
- 最后通过ajax传递到后台去( 这里必须使用:$.ajax()的方式进行传递 —— 这是jQuery中的ajax异步请求方式,即:jQuery对ajax进行了封装,而原理就是上面说的get和post的执行过程。
- 另外:记得对这个ajax设置:cache:false , contentType:false , processData:false
在后台:
- 后台获取这个file中的值是通过 httpServletRequest对象.getParts() 获取file的所有value值( 但是:浏览器不同,这个值不同,所以:需要对这个信息进行截取,得到自己想要的那个文件名( 当然:这个servlet必须加一个注解才可以实现对文件的操作:即 @multipartConfig ) , 不说多了,这个后续会进行演示
3、JSON
1)、JSON是个什么鬼东西?
JSON( JavaScript Object Notation, JS 对象简谱 ) 是一种轻量级的数据交换格式
它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言
易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率
当然:这些都是网上的话,好像不太通俗易懂,那就换一下语言表达
- 用java中能够让人一眼就明白的话来说就是:JSON就是用来存储东西的一个容器,这个容器在传输的时候very地快,同时很容易被解析( 无论是前端还是后台解析 )。这个玩意儿就这么回事儿
2)、JSON这个东西长什么样子嘞?
- 也非常的好理解,在前面说明前端的时候不是玩过js对象吗,这个js对象长什么样子?
{ fieldName1:"value" , fieldName2:"valud" ....... }
JSON对象 / 字符串就长这么个鬼样子
- ' { fieldName1:"value" , fieldName2:"valud" ....... } '
JSON数组长什么样子?
- ' [ { fieldName1:"value" , fieldName2:"valud" ....... } , { fieldName1:"value" , fieldName2:"valud" ....... } ] '
3)、那拿这个JSON来玩的是什么?
- java对象 ---转成---> JSON字符串 / 对象 <---转成---> js对象
(1)、先来玩一下前端中js对象和json对象之间的转换( 其实就只需要记住parse()、stringify()两个方法就完了 )
<script>
// json 对象
var jsonStr = ' {"id":69","name":"苍老师","size":"G"} ';
// json 数组
var jsonArray = ' [{"id":"1","name":"波多野结衣","size":"F"},{"id":"8","name":"汤wei","size":"B"} ] ';
// JSON.parse( json格式的字符串 ) json字符串 = > JS对象(数组) ****重要***
// json对象 转 js对象
var js= JSON.parse(jsonStr);
console.log( js.id , js.name , js.size);
// json数组 转 js对象
var js= JSON.parse( jsonArray );
js.forEach( function (v,i) {
console.log(v.name)
})
// JSON.stringify( js对象 ) JS对象 = > JSON字符串 ****重要****
var perosn = { name:"张三",age:10};
var json = JSON.stringify(perosn);
console.log(json)
</script>
(2)、java对象 转 json对象
- 这个就需要一个jar包了,有如下这些jar包供选择
- fastjson [ 流行 , 所以建议用这个 ]
- jackson
- json-lib
package cn.xieGongZi.servlet;
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ToJson extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset = utf-8"); // 这个其实这里不用配置也行,因为:要响应的是网页才设置这个嘛,这个示例哪里需要响应网页
// 要转成json对象,不让中文乱码,还需要做一件事情
resp.setContentType("application/json;charset=utf-8");
// 这里就直接硬拼一个对象出来
Map<String, Object> map = new HashMap<>();
map.put("name", "紫邪情");
map.put("sex", 18);
map.put("code", 200);
String jsonStr = JSON.toJSONString(map); // 这里就把java对象转成一个json对象了
resp.getWriter().print(jsonStr); // 这一步就是响应给前端
/*
但是:这里涉及到了ajax的使用 [ 其实就是ajax中回调监听哪里的xmlHttpRequest.responseText ] )
请求获取响应文本嘛,这个响应文本内容不就是后台这里的响应流向浏览器发送的数据吗,但是被前端获取过去了
这样前端就可以拿到后端这里传过去的数据了 ———— 不会的,看不懂的,现在不理解没事,等到前后端连起来玩ajax时就懂了
*/
}
}
4、实操玩一下ajax
前面说了这么多理论的废话,没多大意思,所以:还是来实操一手儿ajax吧
使用jQuery中封装好了的ajax
- 要使用jQuery,那肯定需要导入jQuery的js咯
- 要使用jQuery,那肯定需要导入jQuery的js咯
get方式的ajax语法如下:
$.get( ' 后端的接口名-servlet中的那个servlet路径 ' ,{ fieldName1:valued , fieldName2:value .....} , function( 参数 ) {
逻辑代码;
} , 'json' )
- post方式的ajax语法如下:
$.post( ' 后端的接口名-servlet中的那个servlet路径 ' ,{ fieldName1:valued , fieldName2:value .....} , function( 参数 ) {
逻辑代码;
} , 'json' )
- 对如上式子的说明:
{ fieldName1:valued , fieldName2:value .....} 就是要传给后端 ' 后端的接口名-servlet中的那个servlet路径 ' 这个路径下的数据参数
- 这个数据参数的本质其实就是js对象,因此:要是要传的数据参数有多个的时候就可以封装成一个js对象,然后把对象名甩到这里来当数据参数就可以了
'json' 这个就是期望后端传回前端的数据格式类型是什么,具体可以填哪些类型,自行百度百科,这里用json类型
function( 参数 ) 这个就是回调函数 , 这个“ 参数 ”就是后端传给前端的数据( 一般都是json字符串 )
- 这个参数后端一般是怎么封装传过来的?
- 看前端需要的json格式是怎么样的
- 然后通过不断的使用map,从而一层之中套一层...达到想要的json格式,从而使用resq.getWriter().print()把这个json对象传到前端去
- 这个参数后端一般是怎么封装传过来的?
整个过程结合ajax的原生使用方法( 即 : 美没封装之前的用法 —— 前面说的那个三部曲 ), 这样就很好理解了
举个例子( **这个例子很重要很重要 , 后端获取前端的input type = “file”中的信息就是通过这个方法流程得到的 ):
前端需要的格式是这样的:
"errno":0 data:[ { url:"图片地址“ } , { alt:"图片说明“ } , { href:"null" } ] // href 其实是跳转链接
后端就是这么玩的:
package cn.xieGongZi.commons.util.http;
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
// @MultipartConfig 注解就是文件注解,要获取前端的文件信息,必须加这个注解,不然做的所有事情都是无用功
@MultipartConfig
@WebServlet("/ajax/upload.do")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
* 想要构建的是这么一个玩意儿
* "errno":0 data:[ { url:"图片地址“ } , { alt:"图片说明“ } , { href:"null" } ] // href 其实是跳转链接
*
* */
ArrayList<Object> list = new ArrayList<>();
Collection<Part> parts = req.getParts(); // 这是获取前台上传的文件
for (Part part : parts) {
// 先构建 data:[ { } , { } ]中的[ { } , { } ]
// 获取文件的全路径
String filePath = part.getSubmittedFileName(); // 但是:不同浏览器的这个全路径都不一样,所以需要截取从而自定义文件名
// System.out.println(filePath);
// 截取文件的后缀名
int subFileName = filePath.lastIndexOf(".");
String fileSuffix = filePath.substring(subFileName);
// 自己给文件重新定义一个名字,并规定存放的地方
String timeStr = LocalDate.now().toString();
// 获取当前项目的一个指定文件夹名字,用来保存文件 注意:getRealPath这是获取的当前项目的全路径,即:从盘符开始的路径
String proPathName = this.getServletContext().getRealPath("/upload/" + timeStr );
File file = new File(proPathName);
if ( !file.exists() ){
file.mkdirs();
}
// 拼接文件后缀名并保存文件
long timeStamp = new Date().getTime();
part.write(proPathName + "/" + timeStamp + fileSuffix );
HashMap<String, String> map = new HashMap<>();
map.put( "url" , "/upload/" + timeStr + "/" + timeStamp + fileSuffix );
map.put( "alt" , timeStamp + fileSuffix );
map.put( "href" , null );
list.add(map);
}
// 再构建"errno":0 data:[ { url:"图片地址“ } , { alt:"图片说明“ } , { href:"null" } ]
HashMap<String, Object> map = new HashMap<>();
map.put("errno", "0");
map.put("data", list);
resp.getWriter().print( JSON.toJSONString(map) );
}
}
- 前端的html是这样的:
<div id="image">
<label for="">标题图片:</label>
<input type="file" id="file" name="file" >
<img src="" alt="" width="100px" height="150px">
</div>
- 前端的script是这样弄的:
// 当图片发生改变时 —— 也就是用户点击file框,上传文件时
$("#file").on( 'change' , function () {
// 创建一个FormData空对象,就相当于是伪造了一个form表单
let formData = new FormData();
// 这个FromData对象就用来装文件内容
let files = $("#file").prop("files"); // 文件的files属性本质是个数组,可以使用 获取file输入框的节点.files 看一下答案
formData.append("upFile" , files[0] );
$.ajax( { // 这个就是jQuery中ajax的用法,“万变不离其宗”,上面的get和post使用也就会了
url: '/ajax/upload.do',
type: 'post',
data: formData,
dataType: 'json',
cache: false, // 上传文件不需要缓存
contentType: false, // 不需要对内容类型进行处理 因为内容是一个FormData对象
processData: false, // 不需要对数据进行处理,因为上面的data是一个FormData对象
// 后台返回的格式 :
// { "errno":"0" , "data":[ {"alt":"1633528500498.jpg" , "url":"/upload/2021-10-06/1633528500498.jpg"} ] }
success: function (info) {
info.data.forEach( function (data) {
// $("#image img").remove();
// $("#image").append( ' <img src=" '+data.url+' " alt="" width="100px" height="150px"> ' )
/*
注掉的这种是:html中没有img标签时使用
因为:使用下面这种方法的情景是 —— 页面本来就有一个img框( 即:初始页面上这个file本身有一张图片 ),所以下面这种可以做到图片改变时把图片的路径换掉
也就是图片渲染( 这也是数据渲染 / 数据回填 的思想 )
但是:如果页面一开始file的位置是不应该有图片的,是后面用户选了之后才出现图片预览效果,那么:就使用注释掉的这种方法:追加
*、
$("#image img").attr("src" , data.url );
});
}
} );
})
- 这个的效果是这样的,这个图片的信息是可以在后端获取到的( 当然:文件也可以 )
ajax、json的相关内容也就差不多是这些了,主要是:会用就行
javaWeb - 2 — ajax、json — 最后附:后台获取前端中的input type = "file"中的信息 — 更新完毕的更多相关文章
- 获取 input type="file" 标签的内容,并使用ajax进行请求到服务器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- input(type='file')上传多张照片并显示,传到后台
以下内容为网络摘抄和实践修改所得,如有雷同,请谅解!!!! 1.首先是前端页面代码: 其中,<input type="file" id="file_input&qu ...
- js 获取、清空 input type="file"的值 .(转)
上传控件基础知识说明: 上传控件(<input type="file"/>)用于在客户端浏览并上传文件,用户选取的路径可以由value属性获取,但value属性是只读的 ...
- js/jquery 获取本地文件的文件路劲 获取input框中type=‘file’ 中的文件路径(转载)
原文:http://blog.csdn.net/niyingxunzong/article/details/16989947 js/jquery 获取本地文件的文件路劲 获取input框中type= ...
- input type="file"获取文件名方法
文件上传比较丑,样式调整时会有一个获取文件名,或者包含文件路径的文件名的方法 html代码 <div class="file-box"> <form id=&qu ...
- input type="file"文件上传到后台读取
html页面(表单采用bootStrap) js部分: //更换头像时把上传的图片post方式到控制器 <script type="text/javascript"> ...
- input[type='file']获取上传文件路径案例
最近在项目时,需要获取用户的上传文件的路径,便写了一个demo: <body> <input type="file" name="" valu ...
- 获取input type=file 的文件内容(纯文本)
一.获取input type=file 的文件内容(纯文本) 1.需求一 通过点击其他事件,来触发 文件选择框(限定格式为 .c 文件),而不是手动鼠标点击触发. [思路:] step1:将 inpu ...
- js 获取input type="file" 选择的文件大小、文件名称、上次修改时间、类型等信息
文件名的传递 ---全路径获取 $('#file').change(function(){ $('#em').text($('#file').val()); }); 文件名的传递 ---只获取文件名 ...
随机推荐
- 『学了就忘』Linux基础 — 7、补充:安装Linxu系统时设置硬盘挂载说明
目录 (1)新建一个/home分区 (2)再创建一个/boot分区. (3)创建一个swap分区 (4)最后剩余的空间全部分给根目录 (5)总结 上一篇在VMwar虚拟机中安装Linux操作系统中ht ...
- 助你上手Vue3全家桶之Vue3教程
目录 前言 1,setup 1.1,返回值 1.2,注意点 1.3,语法 1.4,setup的参数 2,ref 创建响应式数据 3,reactive 创建响应式数据 4,computed 计算属性 5 ...
- 关于iview、element-ui重置表单并清除校验的方法
平时在使用iview或者vue重置表单是时,我会习惯使用 this.$refs[formData].resetFields(); 但是直接这样写上去方法是不起作用的, 内容必须要在每个form-ite ...
- linux 的 逻辑卷管理
lvm 逻辑卷管理器 关于逻辑卷管理lvm的一些操作 新建磁盘 sdcfdisk /dev/sdc 创建分区,更改分区id 为8e,改变分区类型为 lvm linux 创建物理卷与pv相关 pvcre ...
- Linux 服务器的基本性能及测试方法
1. 摘要 一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息.通常来说运维人员.系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当程序非正常工作 ...
- 学好Python不加班系列之SCRAPY爬虫框架的使用
scrapy是一个爬虫中封装好的一个明星框架.具有高性能的持久化存储,异步的数据下载,高性能的数据解析,分布式. 对于初学者来说还是需要有一定的基础作为铺垫的学习.我将从下方的思维导图中进行逐步的解析 ...
- pip 常用命令小结
pip 常用命令小结 pip这个工具我们经常会用到,毕竟python 是一门以第三方库庞大而著名的编程语言,所以我们总会用pip 安装一些依赖库,当然这只是pip 最常用的一个命令,下面就来介绍一下 ...
- 一、Windows部署RabbitMQ
RabbitMQ官方网站非常详细,以下只是本人学习过程的整理 一.Windows部署RabbitMQ:https://www.cnblogs.com/yangleiyu/p/15539618.html ...
- 常见yaml写法-job
apiVersion: batch/v1 kind: Job metadata: name: job-demo spec: template: metadata: name: job-demo spe ...
- 浏览器调用接口正常,jmeter调不通的可能原因
首先,还是http状态码介绍(网上都能找到这些简介): 1xx 信息,服务器收到请求,需要请求者继续执行操作 2xx 成功,操作被成功接收并处理 3xx 重定向,需要进一步的操作以完成请求 4xx 客 ...