然后再从服务器上的文件中请求数据。
起初,关于文件上传到服务器,这一步我也折腾了很久,主要是不知道将文件上传到哪里。我最开始是在配置文件中设置了一个绝对路径:将文件上传到工程的webapp目录下
picUrl=E:\\workspace\\Login\\src\\main\\webapp
这样的确是可以实现文件上传,但是在请求文件时又出现了问题,这只是一种绝对路径,并不是将文件上传到了服务器上所以在使用jquery的 $.get('/Login/kzn.csv',function(){});并不能获得文件。要将文件上传到服务器上的工程目录的webapp下,应该是使用这样的路径:
String path = request.getSession().getServletContext().getRealPath("/");
可以将path打印输出看到的结果为:
这样在使用 $.get('/Login/kzn.csv',function(){}) 时便可以请求到文件中的数据。
例如我上传的文件在工程中显示如下:
注意这里的$.get()请求中的路径应该写为 '/Login/kzn.csv' 其中Login为工程名,kzn.csv为文件名。所以为了从每次上传的文件中获得内容,只需要知道文件名就可以了。那么如何获得文件名呢?
一开始我一直想的是后台在上传文件时读取文件名,前台通过ajax请求从后台获得文件名,但是遇到了一个问题,ajax请求的数据总是为上次上传的文件名,而不是本次上传的文件名,好像是因为文件上传需要时间,在文件还没上传完时,ajax已经向后台发出了请求,一直到现在我也搞不清楚其中的原因,希望知道的小伙伴可以指点指点我。最后我想了一种办法,直接获取前台页面上显示的文件名
form表单如下:
<form id="uploadForm" enctype="multipart/form-data" target="hiddenFrame"> <table> <tr> <td width="100" align="right">文件:</td> <td><input type="file" name="photo" id="inputFile"/> <iframe name="hiddenFrame" style="display:none"></iframe> </td> </tr> </table> <input type="submit" id="pclick"/> </form> <button id="getdata">获取文件数据</button>
js代码如下:
//下面直接取的页面上提交按钮旁边显示的文件名 $("#pclick").bind("click",function(){ currentFile = document.getElementById("inputFile").value;//此处获得的内容为c:\fakepath\test.csv,所以需要将文件名提取出来 index = currentFile.lastIndexOf("\\"); fileName = currentFile.substring(index+1); photo(); //return false,会造成得不到文件的内容,我利用一个隐藏的iframe来放置内容 });
接着通过点击按钮便可以获得提交文件中的数据:获得数据函数getDataFromFile(name)如下:
function getDataFromFile(name){ $.get('/Login/'+name,function(csvString){ $('#display').html(csvString); }); }
按钮点击事件如下:
$("#getdata").bind('click',function(){
getDataFromFile(fileName);
});
完整的js代码为:
var fileName; $(document).ready(function(){ var currentFile,index; //下面直接取的页面上提交按钮旁边显示的文件名 $("#pclick").bind("click",function(){ currentFile = document.getElementById("inputFile").value; index = currentFile.lastIndexOf("\\"); fileName = currentFile.substring(index+1); photo(); //return false,会造成得不到文件的内容,我利用一个隐藏的iframe来放置内容 }); $("#getdata").bind('click',function(){ getDataFromFile(fileName); }); }); /*-----------------------------------------------------------------------------------*/ /*-----------------获得后台传过来的数据,但是这种情况下实现了两次ajax请求,第一次是form表单的action,第二次是下面的ajax中定义的url请求-----------------------------------------------------------------*/ function photo(){ $.ajax({ async:false,//同步,意思是当有返回值以后才会进行后面的js程序 type:'get',//get是获取数据,post是带数据的向服务器发送请求 url:'addAction.do',//dataType:'text',success:function(data){ var val=eval(data);//转换成js对象 alert("文件上传成功:"+val); },error:function(data){ alert("文件上传失败,请重新上传!"); } }); } function getDataFromFile(name){ $.get('/Login/'+name,function(csvString){ $('#display').html(csvString); }); }
这样便可以上传文件,并通过文件名发起请求获得文件中的数据。虽然达到了我想要的效果,但是还是有上面说到的问题没解决。我之前说我每次通过ajax请求获得的数据都是上一次ajax请求的数据,我终于知道了原因了:我发送了两次ajax请求,form表单中定义的action进行了一次请求,photo()中定义的ajax又发送了一次请求,所以发送了两次请求,相应的数据获得了两次。接着,我改正了这个错误,只在表单中进行请求。
实现js代码如下:
var fileName; $(document).ready(function(){ /*下面这种方式真正实现了从后台传递到前台的数据*/ $('#uploadForm').submit(function(){ $(this).ajaxSubmit({ type:'post',url:'addAction.do',success:function(data){ fileName=eval(data); alert("提交成功:"+data); } }); return false;//阻止表单默认提交 }); $("#getdata").bind('click',function(){ getDataFromFile(fileName); }); }); function getDataFromFile(name){ $.get('/Login_ssm_mav_waterfull/'+name,function(csvString){ $('#display').html(csvString); }); }
这样便可以获得从后台传过来的文件名了。
后台文件上传我是用SpringMVC写的,代码如下:
@Controller @Configuration @ImportResource("classpath:spring.xml") @RequestMapping("/photo") public class FileUploadController { @Resource private IPhotoService photoService; private String fileName = ""; public void setPicUrl(String picUrl) { this.picUrl = picUrl; } @RequestMapping(value = "/tofile") public String toFileUpLoad(HttpServletRequest request,Model model) { return "fileUpLoad"; } @RequestMapping(value="/addAction.do") @ResponseBody public String save(HttpServletRequest request,HttpServletResponse response,Model model,@RequestParam(value = "photo",required = false) MultipartFile filedata) throws UnsupportedEncodingException { response.setCharacterEncoding("UTF-8"); response.setHeader("Cache-Control","no-cache"); response.setDateHeader("Expires",0); /* response.setContentType("application/json");*/ int pre=0; int fina=0; int dur=0; JSONArray jsonArray = new JSONArray(); for (int i = 10; i < 30; i++) { Photo p = photoService.getPhotoById(new BigDecimal(i)); jsonArray.add(p); } if (filedata != null && !filedata.isEmpty()) { pre=(int)System.currentTimeMillis(); // 获取图片的文件名 fileName = filedata.getOriginalFilename(); // 将图片上传到服务器 fina=saveFile(request,fileName,filedata); dur=fina-pre; System.out.println("上传文件 "+fileName+" 耗时: "+dur); } return fileName; } private int saveFile(HttpServletRequest request,String newFileName,MultipartFile filedata) { int finalTime=0; String path = request.getSession().getServletContext().getRealPath("/"); System.out.println("路径:" + path);// 输出为:路径:C:\Program Files\Tomcat7.0\wtpwebapps\Login_ssm_mav_waterfull\ String saveFilePath = path; // 构建文件目录 File tempFile = new File(saveFilePath); if (!tempFile.exists()) { tempFile.mkdirs(); } // 保存文件到服务器 FileOutputStream fos; try { fos = new FileOutputStream(saveFilePath + "\\" + newFileName); fos.write(filedata.getBytes()); fos.close(); finalTime=(int)System.currentTimeMillis(); }catch (Exception e) { e.printStackTrace(); } return finalTime; } }这样便可以完成文件上传及获得文件中的数据了。