利用jqueryFrom传文件到servlet,以及两个服务器之间传文件和其他数据

项目背景:有两个服务器,一个是用户操作的手机端服务器,一个是后台(响应前一个服务器,并能访问数据库)
项目需求:用户从手机端上传身份证以及个人信息,我们需要将数据传给后台,并且在信息认证通过后将身份证照片存在后台服务器的D盘文件夹下。
需要的jar包:commons-fileupload-1.3.3.jar ; commons-io-2.6.jar
下载链接:www.baidu.com
哈哈哈,皮了一下,真正的下载方式是:百度那两个jar包名称,去官网下,是免费的(狗头)
jqueryForm上传数据是利用的表单提交,下面是html页面的form:

<form id="form1" action="../registerRealInfo" method="post" enctype="multipart/form-data" class="mui-input-group">
					<input type="hidden" id="loginName" name="loginName"/>
					<input type="hidden" id="loginPwd" name="loginPwd"/>
					<div class="mui-input-row">
						<label id="reName">真实姓名</label>
						<input type="text" id="realName" name="realName" autocomplete="off" class="dev-input" placeholder="请输入身份证上的真实姓名" value="" />
					</div>
					<div class="mui-input-row">
						<label id="reNum">身份证号码</label>
						<input type="text" id="IDCardNum" maxlength="18" name="IDCardNum" onkeyup="value=value.replace(/[\u4E00-\u9FA5]/g,'')" autocomplete="off" class="dev-input" placeholder="请输入18位身份证号码" value="" />
					</div>
					<div class="title img-title" id="reImage">证件图片</div>
				    <ul class="mui-table-view mui-grid-view">
				        <li class="mui-table-view-cell mui-col-xs-12">
				            <a href="#">
				            	<div class="image-box">
									<input type="file" name="IDCardImage" id="IDCardImage" accept="image/*"  class="choseBtn" />
									<div id="forsee" class="upImageBox"></div>
				                </div>
				                <div class="mui-media-body" id="IdCard">身份证个人信息面</div>
				            </a>
				        </li>
				    </ul>    
				</form>

下面是js方法,利用jqueryForm的ajaxSubmit可实现异步的表单提交:

  		$('#comRegister').click(function(){
            var options = {
                url: "../registerRealInfo", //提交地址:默认是form的action,如果申明,则会覆盖
                type: "post",   //默认是form的method(get or post),如果申明,则会覆盖
                beforeSubmit: beforeCheck, //提交前的回调函数
                success: function (data) { //提交成功后的回调函数
					if(data.result=="success"){
						$(location).attr('href','registerSuccessful.html?loginName='+loginName);
					}else if(data.result=="true"){
                        if(data.resultMsg == 1){//身份信息验证失败
                            mui.toast(infoWrong);
						}else if(data.resultMsg == 2){//身份证图片验证失败
                            mui.toast(photoWrong);
                        }else if(data.resultMsg == 5){//每台设备每天认证次数限5次,请明天再来
                            mui.toast(timesLimited);
                        }
					}else if(data.result=="false"){
					    mui.toast(registerFail);
					}else if(data.result=="done"){
                        mui.toast(alreadyDone);
                    }
                },
                error:function (data) {
                    mui.toast(programError);
                },
                target: "#output",  //把服务器返回的内容放入id为output的元素中
                dataType: "json", //html(默认), xml, script, json...接受服务端返回的类型
                clearForm: false,  //成功提交后,是否清除所有表单元素的值
                resetForm: false,  //成功提交后,是否重置所有表单元素的值
                timeout: 300000     //限制请求的时间,当请求大于300秒后,跳出请求
            };
            $('#form1').ajaxSubmit(options);
	  	});

**异步的表单提交的目的:**常规的表单提交,无论后台如何反馈信息,都会刷新页面,而jqueryForm的ajaxSubmit既可实现表单提交,也能实现ajax的功能,保证页面不会刷新,等待后台返回结果,再进行需要的操作。那么为什么不用ajax呢,因为ajax不能传文件。
下面是后台servlet接收前端传来的数据:

public class RegisterInfoServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        HttpSession session = request.getSession();
        String ip = Util_GetData.getInboundIp(); //获取IP
        String deviceName = Util_GetData.getDeviceSN();
        String resultMsg = "";
        String url = "http://"+ip+"/deviceRegister";
        DiskFileItemFactory factory = new DiskFileItemFactory();//从这里开始接受前端的数据 貌似用这个方法需要两个jar包
        // 创建一个文件上传解析器
        ServletFileUpload upload = new ServletFileUpload(factory);
        Map<String, String> strParams = new HashMap<>();
        String loginName=null;
        List<FileItem> list = null;
        String filename=null;
        InputStream stream=null;
        try {
            list = upload.parseRequest(request);//获取到前端所有的数据(即表单里有name属性的标签)
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        for(FileItem item : list) {//遍历这个list
            if (item.isFormField()) {//如果fileitem中封装的是普通输入项的数据
                String name = item.getFieldName();
                String value = item.getString("UTF-8");
                strParams.put(name,value);
                if(name.equals("loginName")){
                    loginName = value;
                }
                continue;
            } else {//如果fileitem中封装的是上传文件
                stream = item.getInputStream();//上传文件需要的文件流参数 如果只有单个文件,这里就已经获取了文件的InputStream
                filename = item.getName();//上传文件需要的参数 这里获取了文件名称
            }
        }
        HttpConnectionUtil cnnUtil = new HttpConnectionUtil();
        strParams.put("deviceName",deviceName);//把所有普通数据放入Map
        resultMsg = cnnUtil.uploadFile(url,stream,filename,strParams);//调用这个方法访问另一个服务器,此方法紧跟在下面
        if(null != resultMsg && !"".equals(resultMsg) && resultMsg.indexOf("success") > 0){
            session.setAttribute("loginName", loginName);
        }
        PrintWriter pw = response.getWriter();
        pw.print(resultMsg);
        pw.flush();
        pw.close();
    }
}
//访问后台服务器的方法
package com.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import java.util.UUID;

/**
 * Java原生的API可用于发送HTTP请求,即java.net.URL、java.net.URLConnection,这些API很好用、很常用,
 * 但不够简便;
 *
 * 1.通过统一资源定位器(java.net.URL)获取连接器(java.net.URLConnection) 
 * 2.设置请求的参数 
 * 3.发送请求
 * 4.以输入流的形式获取返回内容 5.关闭输入流
 * @author H__D
 *
 */
public class HttpConnectionUtil {

    private static final int TIME_OUT = 80 * 1000;                          //超时时间
    private static final String CHARSET = "utf-8";                         //编码格式
    private static final String PREFIX = "--";                            //前缀
    private static final String boundary = UUID.randomUUID().toString();  //边界标识 随机生成
    private static final String CONTENT_TYPE = "multipart/form-data";     //内容类型
    private static final String LINE_END = "\r\n";




    /**
     * 文件上传的方法
     *
     * @param actionUrl:上传的路径
     * @param filename:文件名称
     * @param stream:上传文件需要的文件流参数
     * @return
     */
    public String uploadFile(String actionUrl, InputStream stream,String filename,Map<String, String> strParams) {


        DataOutputStream ds = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();

        try {
            // 统一资源
            URL url = new URL(actionUrl);
            // 连接类的父类,抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;

            // 设置是否从httpUrlConnection读入,默认情况下是true;
            httpURLConnection.setDoInput(true);
            // 设置是否向httpUrlConnection输出
            httpURLConnection.setDoOutput(true);
            // Post 请求不能使用缓存
            httpURLConnection.setUseCaches(false);
//            httpURLConnection.setReadTimeout(TIME_OUT);
//            httpURLConnection.setConnectTimeout(TIME_OUT);
            // 设定请求的方法,默认是GET
            httpURLConnection.setRequestMethod("POST");
            // 设置字符编码连接参数
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            // 设置字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            // 设置请求内容类型
            httpURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE+";boundary=" + boundary);

            // 设置DataOutputStream
            ds = new DataOutputStream(httpURLConnection.getOutputStream());
            //参数上传
            ds.write(getStrParams(strParams).toString().getBytes());//普通数据上传完成,这里有个方法包装普通数据的Map,在下面
            ds.flush();

            StringBuilder fileSb = new StringBuilder();            //文件上传
            fileSb.append(PREFIX)
                    .append(boundary)
                    .append(LINE_END)
                    /**
                     * 这里重点注意: name里面的值为服务端需要的key 只有这个key 才可以得到对应的文件
                     * filename是文件的名字,包含后缀名的 比如:abc.png
                     */
                    .append("Content-Disposition: form-data; name=\"file\"; filename=\""
                            + filename + "\"" + LINE_END)
                    .append("Content-Type: image/jpg" + LINE_END) //此处的ContentType不同于 请求头 中Content-Type
                    .append("Content-Transfer-Encoding: 8bit" + LINE_END)
                    .append(LINE_END);// 参数头设置完以后需要两个换行,然后才是参数内容
            ds.writeBytes(fileSb.toString());
            ds.flush();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = stream.read(buffer)) != -1) {
                ds.write(buffer, 0, length);
            }
            stream.close();
            ds.writeBytes(LINE_END);
            //请求结束标志
            ds.writeBytes(PREFIX + boundary + PREFIX + LINE_END);
            ds.flush();
            ds.close();                                      //文件上传完成
            if (httpURLConnection.getResponseCode() >= 300) {
                throw new Exception("请求失败:" + httpURLConnection.getResponseCode());
            }

            if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                inputStream = httpURLConnection.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream);
                reader = new BufferedReader(inputStreamReader);
                String tempLine = null;
                resultBuffer = new StringBuffer();
                while ((tempLine = reader.readLine()) != null) {
                    resultBuffer.append(tempLine);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ds != null) {
                try {
                    ds.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return resultBuffer.toString();
        }
    }

    private static StringBuilder getStrParams(Map<String,String> strParams){
        StringBuilder strSb = new StringBuilder();
        for (Map.Entry<String, String> entry : strParams.entrySet() ){
            strSb.append(PREFIX)
                    .append(boundary)
                    .append(LINE_END)
                    .append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINE_END)
                    .append("Content-Type: text/plain; charset=" + CHARSET + LINE_END)
                    .append("Content-Transfer-Encoding: 8bit" + LINE_END)
                    .append(LINE_END)// 参数头设置完以后需要两个换行,然后才是参数内容
                    .append(entry.getValue())
                    .append(LINE_END);
        }
        return strSb;
    }

}

文件上传很艰难,文件接受更艰难。之前有过很多上传文件的方式,但苦于不知道后台该如何接收文件。这次的接收方式也很奇葩。

	//设备注册并实名认证
	@RequestMapping(value = "/deviceRegister")
	@ResponseBody
	public String deviceRegister(HttpServletRequest req, HttpServletResponse res, @RequestParam("file") MultipartFile file, @RequestParam("loginName") String loginName, @RequestParam("loginPwd") String loginPwd, @RequestParam("realName") String realName, @RequestParam("IDCardNum") String IDCardNum, @RequestParam("deviceName") String deviceName){
		//数据传送完成,开始你的表演
	}

没错,上面接收数据的方式就是在方法体里面,通过@RequestParam和所有的name,接收对应的数据。
后续还会有各种情况和各种架构下,传递+接收文件的博客,哪天心情好就写咯,反正都是我工作里面碰到的,第一次开发,又没有经验,只能到处百度,到处拼接方法这样子,唉,说不出的滋味。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值