form表单提交数组java,表单form的提交和servlet的取值

表单form的提交和servlet的取值

一、前言

对于后端开发来说,经常要和前端进行联系的两个面就是:1、表单form提交至servlet。2、ajax提交至servlet进行处理。

显然,有必要对这两个常用的功能进行一次梳理。

1、一个中文乱码的坑

在表单传值和后台进行交流的时候,一个最大的坑就是中文的乱码问题了。这个坑的具体分析不过多阐述,最佳实践就是: 使用post 方式进行数据的提交,后台设置字符集过滤器,对request、response 的字符集都设置为utf-8 。

2、表单form的enctype字段

HTML表单如何打包数据文件是由enctype这个属性决定的。enctype有以下几种取值:

application/x-www-form-urlencoded在发送数据之前,编码所有字符(空格被编码为’+’,特殊字符被编码为ASCII十六进制字符,中文会被编码,英文不会)。此时,数据是以编码后的字符串形式进行传输。

multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。此时,数据是以二进制流的形式进行传输。

text/plain 空格转换为 “+” 加号,但不对特殊字符编码。

默认值是enctype=application/x-www-form-urlencoded,所以表单的内容会按URL规则编码,然后根据表单的提交方法:

method="get" ,编码后的表单内容附加在请求连接后

method="post" ,编码后的表单内容作为post请求的正文内容

二、使用action 的表单

前端的表单,在填写了数据之后将数据发送给后端进行处理。这里,我们所指的表单意为通过action 字段进行提交,通过ajax 模拟提交的情况放在下一大点中讨论。

而这里的表单又分为2种情况:

表单form单纯的只有数据项,只提交文本数据,通常是key-value 的形式,对于复选框亦如此。

表单form既有文本数据项,又有文件数据,即包含 字段。

1、只提交文本数据的表单

例如表单:

male

female

primary

middle

high

basket

tennis

football

在servlet中获取数据:

String username = request.getParameter("username");

String sex = request.getParameter("sex");

String education = request.getParameter("education");

String[] hobby = request.getParameterValues("hobby");

解读

数据编码: 对于纯文本的表单,其字段enctype=application/x-www-form-urlencoded 是默认值,表示表单的数据进行url编码,如:表单的数据被编码成username=123&password=222 。

传输方式: 数据传输方式method : 如果使用get ,那么该字符串会追加到请求的url地址后面;而如果使用post ,那么打开调试台,查看Form Data 项也可以查看到字符串。

这种表单提交数据的方式最为简单。

2、提交文本数据和文件数据的表单

例如表单:

在servlet中获取数据以及保存文件:

因为传输过来的是二进制流,因此无法使用getParameter() 等现成的方法来获取值。推荐使用apache upload 框架来进行数据的读取操作。当然,servlet也有原生的方法来获取,参考(https://docs.oracle.com/javae... 、(https://docs.oracle.com/javae... 。

解读

传输方式: 因为是二进制流, 所以method 只能使用post 进行提交,无法使用get 。

3、servlet的处理再谈一谈

既然我们在servlet中可以获取到表单传过来的值了,那么我们的返回又应该是什么样的呢?对于使用action 提交的表单,我们的servlet必须将请求转发或者使用重定向,以此进行页面的切换(跳转)。如果想携带新的数据,只能在请求转发的request 对象上进行数据的添加。

请求转发:

request.setAttribute("msg","登录成功!"); // 携带数据

request.getRequestDispatcher("/success.jsp").forward(request,response);

重定向:

response.sendRedirect("/webapp/success.jsp");

解读

很明显,直接使用action 提交是很不好的。因为在提交至servlet时,地址栏的路径会变成指向servlet的路径,而这时候,如果使用请求转发的话,那么地址栏的路径并不会改变,这样就不是很优雅。而如果使用重定向的话,就无法携带数据,对于常见的登录验证(需要错误信息)就无法完成了。另一个缺点就是,无论是请求转发还是重定向,原本填写的表单数据都被清空,这样是极为糟糕的。

表单提交的最常见场景,往往就是用户登录或者是文件上传,这些都需要服务器做出反馈,鉴于上面所说的缺点,我们就不会使用action 的表单,而是使用更为强大ajax技术。

三、使用ajax技术,模拟表单提交

前言:

我们先聊一聊ajax技术,ajax是发起一个http请求,当然可以携带数据,这个数据是以字符串的形式来传输的。当然,这个请求被发送至servlet进行处理,servlet返回处理后的信息,这个信息被ajax的回调函数所接受,然后ajax就可以进行相应的操作了。

当使用ajax时,可以没有表单的存在,因为我们不需要action 了,我们只需要得到要传输的数据即可。同时,对于type="submit" 字段也要小心设置,因为我们其实可以不设置该值,或者在js事件中进行表单提交的判断。

区别:

ajax的过程和表单提交几乎差不多,不同的是:ajax发出的http请求并不是浏览器发出的请求,因此servlet是没有办法影响页面的跳转的 ,所以要想进行页面的跳转只能是ajax的回调函数中进行处理。并且大多数时候,servlet的处理也会返回json 数据至前台。这里的话,就涉及到json 数据的反序列化和java 对象(或者是Map 、List )的序列化了。

缓存: ajax发出的请求通常会被浏览器缓存,因此我们可以应该拒绝缓存。通常是在url地址后面追加一个随机字符参数,而使用jquery的ajax可以设置cache:false 这个属性就ok了。

jquery的ajax:

因为原生的ajax技术代码较多,因此我们使用jquery封装好的ajax函数来讲解其用法。在jQuery中,$.ajax() 方法属于最底层的方法,第2层是$.load(),$.get(),和$.post(),第3层是$.getScript()和$.getJSON() 方法。第2、3层都是调用了第1层来实现的。

1、一个提交后页面自动刷新的坑

有时候,在点击提交之后,页面会自动刷新,我们无法查看相关的数据,这是一个大坑。正确的解决方法,使用 这个按钮来进行事件绑定并提交。当然,这是针对ajax来用的。

2、 仅发送请求至servlet,接收返回数据

当我们不需要发送数据的时候,其实只需要在一个js的事件中使用ajax就可以了,不需要表单。这种方式实际用的比较少。

一个触发ajax的按钮:

ajax_1

jquery代码:(请求servlet,接收返回数据)

var bt_1=$("#bt_1");

bt_1.on("click",function () {

$.ajax({

url:"/webTest/ajax1", // 请求的servlet

type:"post", // 因为没有携带数据,无所谓

async: true, // 异步

cache: false, // 不许缓存

success:function(data){ // 请求成功,200

console.log(data);

},

error:function(error){ // 请求失败

console.log(error);

}

})

})

servlet处理代码:(返回数据)

PrintWriter out = null;

try {

out = response.getWriter(); // 打开response的输入流

} catch (IOException e) {

e.printStackTrace();

}

out.print("I give u a feedback"); // 写入信息到response

out.close();

3、 携带文本数据,发送请求至servlet,接收返回数据

有的时候,我们需要携带一些数据,可以是常见的表单,也可以是一些零散的数据。在这种情况下,我们需要将数据封装成json 数据格式进行传输。

3.1 第一种封装的json 数据:对象形式

jquery代码:

var sub=$("#sub");

sub.on("click",function () {

$.ajax({

url:"/webTest/ajax2",

type:"post",

async:true,

cache: false,

data: { // json数据(注意,不能使用JSON.stringify()方法,否则出错)

"username": "liSi",

"password": "ps"

},

success:function(data){

console.log(data);

},

error:function(error){

console.log(error);

}

})

})

servlet处理代码:(接收数据,返回数据)

String username = request.getParameter("username");

String password = request,getParameter("password");

PrintWriter out = null;

try {

out = response.getWriter(); // 打开response的输入流

} catch (IOException e) {

e.printStackTrace();

}

out.print("I give u a feedback"); // 写入信息到response中

out.close();

解读

在这种情况下,封装的json数据因为比较简单,所以数据被编码成字符串发送至servlet,就和之前使用action 的表单提交文本数据的情况一样。

注意,一旦json 数据复杂一点点,如{"username":"liSi","hobby":{"todya":"ttennis"}} ;就无法使用getParameter("hobby") 来获取数据了,这也是下面要将的第二种封装的json 数据。显然,这种封装的json 数据的获取,是一种特殊情况,在大多数不复制的情况是一种很好的方式。

技巧

当我们使用了表单的时候,如果我们只是想传输表单的值,那么就没有必要手工取值化成json形式,jquery提供了相应的方法来简化操作。当然,只是针对文本数据而言。

jquery代码1:

var data_json = $("#form_1").serialize();

data: data_json,

这里通过序列化函数,会自动把表单的数据转化为字符串形式(url),也就是和action 表单提交一致的效果。在servlet中可以直接通过getParameter() 方法来获取参数。

jquery代码2:

var data_json = $("#form_1").serializeArray();

data: data_json,

这里通过序列化函数,会自动把表单的数据转化为json数据格式,省去了手工封装成json的过程。

3.2 第二种封装的json 数据:数组形式

一旦json 数据变复杂,那么在servlet中就无法通过getParameter() 获取数据了。这个时候我们需要把json 数据先字符串化,使得json 在传输的时候就是原数据(打开调试台看到的Form Data 就和json 原数据一样)。

jquery代码:

var sub=$("#sub");

var data_json=[{"sex": '男',"submit":"111"},{"sex": '女',"submit":"222"}];

sub.on("click",function () {

$.ajax({

url:"/webTest/ajax2",

type:"post",

async:true,

cache: false,

data: JSON.stringify(data_json), // 先序列化json数据

success:function(data){

console.log(data);

},

error:function(error){

console.log(error);

}

})

})

在这里,json 数据就是比较复杂的了,我们要先使用JSON.stringify() 序列化json 数据。

servlet代码:

BufferedReader reader = request.getReader(); // 获取请求的输出流

String jsonData = "";

jsonData += reader.readLine();

reader.close();

// 获取到一致的json数据

System.out.println(json); // [{"sex": '男',"submit":"111"},{"sex": '女',"submit":"222"}]

java操作json 数据:

对于得到的json 数据,我们需要反序列,把我们需要的值给取出来。通常是使用json 的解析库,如GSON、fastJson等。这里我们使用GSON来讲解。

由于篇幅的原因,GSON 操作json 数据,序列化与反序列化的内容在另一章中进行讲解。总之,我们可以操作任何复杂的json 数据,并且从中取出我们需要的属性。

解读

得益于json 数据格式,使得前后端之间的数据交流变得十分方便。具体如何在java中操作json,请看有关于json的文章。

3.3 jquery的ajax 技术参数解读

在ajax的代码中,有几个参数比较重要。

1、 contentType: "application/json;charset=utf-8"

这个参数是指明提交的数据的数据类型,不指明的话,默认是:

Content-Type: application/x-www-form-urlencoded; charset=UTF-8 。

而指明了数据格式为json 的话,在后台有些框架可以直接获取,比如说springmvc。

注意: 一旦使用了指明了数据类型是json之后,就应该使用JSON.stringify() 方法来处理json数据。在后台的处理程序中就无法使用getParameter() 方法来获取值了。

2、 dataType:"json"

这个参数是指明返回的数据的数据类型,不指明的话,默认是:"text" 。

4、 携带文本数据和文件数据,发送请求至servlet,接收返回数据

同样的一句话,只要涉及到文件数据,那么就是二进制流传输,是无法使用getParameter() 直接获取数据的。并且再啰嗦一句,之所以推荐使用ajax,就是因为它可以做到页面不跳转的提交。

4.1 使用FormData对象

我们还是可以选择是否使用表单,这也无所谓。当multiple="multiple" 时,可以一次上传多个文件。

表单:

jquery代码:

var formData = new FormData();

var name = $("input").val();

// formData对象放入值

formData.append("name",name);

formData.append("file",$("#file")[0].files[0]); // 只选择第一个文件

$.ajax({

url : Url,

type : 'POST',

data : formData,

processData : false, // 告诉jQuery不要去处理发送的数据

contentType : false, // 告诉jQuery不要去设置Content-Type请求头

success:function(data){

console.log(data);

},

error:function(error){

console.log(error);

}

});

当然,我们可以直接传入表单对象。这样更加快速。

var form_1 = document.getElementById("form_1");

var formData = new FormData(form_1);

data: formData,

四、谢幕

关于前端的表单提交数据至后台servlet的总结就先告一段落了。内容上可以分成2块,一是直接使用action 的表单提交,二是使用ajax 技术模拟的表单提交。而在数据上又可以分成2块,一是只含有文本数据,而是含有上传文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值