BBC.地平线.大数据时代
“在洛杉矶,警方通过数据分析,预测12小时内哪个地区最有可能发生犯罪;在伦敦金融城,一位交易员认为,数学计算可成为发财”秘笈”;在南美,天文学家尝试为整个宇宙进行分类记录……这些迥然不同的领域如今出现同一特征:数据量的大爆发。”
这是英国广播公司品牌栏目《地平线》最新播出的纪录片《大数据时代》中的开篇一幕。
一个程序员的喃喃自语
“在洛杉矶,警方通过数据分析,预测12小时内哪个地区最有可能发生犯罪;在伦敦金融城,一位交易员认为,数学计算可成为发财”秘笈”;在南美,天文学家尝试为整个宇宙进行分类记录……这些迥然不同的领域如今出现同一特征:数据量的大爆发。”
这是英国广播公司品牌栏目《地平线》最新播出的纪录片《大数据时代》中的开篇一幕。
JNAN DASH的一位(IBM数据仓库BI)专家朋友几周前参加了在圣何塞举行的Hadoop会议。两年前也是这个时间,他参加了当时在纽约的Hadoop会议,但当时仅有200人,而这次不仅有2000多人参加,并且门票早已销售一空。显然,这很直观地证明了Hadoop会议引发了业内高度的兴趣。不止如此,他发现每一个主题演讲的PPT中有关Hadoop技术的幻灯片中都提到“我们正在招聘(we are hiring)”。
人才缺乏由此可见一斑。作为一个能够对大量数据进行分布式处理的软件框架,Hadoop可靠、高效而可伸缩。由于Hadoop很容易实现对搜索关键字进行内容分类,并可以通过并行处理加快处理速度,所以受到更行业的欢迎。而Hadoop带有用Java 语言编写的框架,因此在Linux生产平台上很理想。而在Hadoop上的应用程序也可以使用其他语言编写,比如 C++。
事实上,Hadoop使廉价服务器的大规模并行计算成为可能。企业可以收集更多的数据,保留时间可以更长,并对所有数据可以进行之前由于成本、复杂性和缺乏工具而无法进行的分析。互联网企业几乎都是Hadoop的用户,而如eBay、Facebook、LinkedIn、Netflix和Twitte的创新型尝试也为其他数据密集型行业,如金融、科技、电信和政府的应用铺平了道路。越来越多的IT人发现,Hadoop已经在其架构规划中占据一席之地。但Hadoop成为绝对主流的另一大挑战是,如何找到擅长这一技术的专业人才。
Cloudera、IBM、Hortonworks、MapR是值得关注的四家Hadoop企业。而这几家都有大量投资于培训计划,教IT专业人员如何部署,配置和管理Hadoop的产品。显然,这些企业清楚地认识到,人才将是限制Hadoop企业级应用发展不容回避的问题。
但另一面,Cloudera的客户解决方案副总裁Omer Trajman却表示:“直接雇佣新人是不可思议的。”在他看来,“最可行的办法是在企业内部寻找人才来学习Hadoop。”因为,“最成功的公司一般不需要大举招聘。因为在企业内部,完全可以了解员工的基本技能,比如谁有科学、统计、数据处理、利用Java来开发和分析的背景,找到这些已经在相关业务领域中拥有专门知识的人才,然后再做Hadoop培训,教会他们如何使用Hadoop工具,就可以成为合格的人才。”
当然,随着对Hadoop的重视程度更高,业内学习Hadoop的人也在增加。相关业内人士表示:“几年前我在面试技术人员时,问他们是否认识Hadoop?而通常的答案是ha-what?但是如今,知道和运用Hadoop的人已经越来越多了。”
不过,问题也随之而来。企业需要明确什么样类型的人是适合招聘的Hadoop人才?
“我们原以为需要找一个铁杆的Java开发者”,MapR商业分销Return Path的负责人表示,“但事实并非如此。最适合Hadoop的人才不一定是Java工程师。反而是那些能够理解集群、收集一些工具,指出如何实现协同工作,并能处理Hadoop生态系统中出现的许多问题,而并不仅限于Hadoop 1.0的人才是我们需要的技能型人才。”
这篇文章发表在:2012-07-13
[爆笑体育]完整版 第十三期 20130624 还是要笑一笑O(∩_∩)O哈哈~
想请教一下,在招聘hadoop方向的开发人员时,和招聘web应用开发人员的要求有什么不同,是否会更看重算法设计能力。对于目前从事web开发,想要转至hadoop方向的程序员有没有什么好的建议呢?谢谢!
我的规划中,是没有“专业Hadoop程序员”这个概念的。毕竟这只是一个框架,就好像不能叫“专业Mysql管理员”一样,我们应该是从事分布式计算的工程师,或者云计算工程师。
做这个领域,我认为有两个方面的能力是重要的,技术架构能力和业务数据敏感。
针对目前从事Web开发的工程师,我第一个建议是提高视野。很多Web工程师只认识Web框架内的东西,这阻碍他理解批处理系统的结构。
第二个建议是要对业务数据敏感,大部分Web工程师长期接触一线的需求,这方面是没有问题的。
你说的算法设计能力,我认为是技术能力的一部分。在入门阶段不是很紧迫,做1-2年以后会遇到需要优化的算法问题。
关于第一个问题,招聘时的区别。在我这里是没有的,任何领域的开发人员我们都要求 1 基础扎实 2 逻辑清晰 3 沟通流畅,知识可以慢慢学,但是素质不容易改。
知乎: http://www.zhihu.com/question/19956296
在Facebook总部的一次开发者会议上,这个社交网络巨头的工程师透露,他们正在使用新的自主研发的查询引擎Presto,在已有的250PB的庞大数据仓库上进行交互式分析。
据Martin Traverso工程师透露,有超过850名Facebook工程师每天用它来扫描超过320TB的数据。在以前,我们的科学家和分析师一直依靠Hive来做数据分析。但Hive是专为批处理设计的。但随着数据越来越多,Hive已不能满足我们的需求。虽然我们还有其他比Hive更快的工具,但它们要么在功能有所限制要么就太简单,以至于无法操作我们庞大的数据仓库。而在过去的几个月中,我们一直使用Presto来填补这方面的空白。
Hive是Facebook在几年前专为Hadoop打造的一款数据仓库工具。因为它主要依赖MapReduce进行运行,所以随着年龄的上升,其在速度上已不能满足日益增长的数据要求。浏览一个完整的数据集可能要花费几分到几小时,这完全是不切实际的。
Traverso还表示,使用Presto进行简单的查询只需要几百毫秒,即使是非常复杂的查询,也只需数分钟即可完成,它在内存中运行,并且不会向磁盘写入。
虽然看起来Presto如同Facebook版的Cloudera Impala SQL查询引擎,或与Hortonworks在Stinger项目中所做的事情相似,但这是按照Facebook规模为实现更快操作而定制的版本。Presto并不会与其他商业产品进行竞争,但它会很快让大数据行业产生不小的震动。并且Facebook打算在今年秋天以开源的形式发布Presto。
Facebook的工程经理Ravi Murthy表示,随着用户量地不断增长,数据仓库也在快速增长,它比四年前要大4000倍。Murthy 也表示,在接下来几年,数据将会达到艾字节。因此,为了适应这种数据规模,我们不得不重新考虑许多东西。
Presto则是其中之一,除了提高查询速度,在CPU使用效率上,这个引擎比Hive高效7倍。另外一个正在进行的项目是缩减Facebook数据中心的分析数据空间。
Ashton Kutcher主演的乔布斯传记电影Jobs今天发布了首段预告片,为大家展示了这部电影的基本概况。Jobs在今年的圣丹斯电影节上举行了首映,影评网站对这部电影的评价褒贬不一。这部电影原计划在今年4月公映,不过一直被推迟至今年8月16日。
Jobs电影中,Ashton Kutcher将扮演乔布斯,Josh Gad版本Steve Wozniak。早在今年4月,搞笑视频网站Funny or Die就发布了不受好评的iSteve喜剧风格乔布斯传记电影,其中乔布斯的扮演者是Justin Long,他曾经在Mac vs PC广告系列中扮演Mac角色。
最后,由Aaron Sorkin担任编剧的得到Walter Isaacon官方授权的乔布斯传记电影目前还在制作初期,这部电影计划讲述乔布斯的人生的三个阶段,也就是发布原始Mac、NeXT和发布iPod,每个阶段大概30分钟左右。
为什么Windows Azure要拥抱Hadoop?
Hadoop已经有一个非常完整的生态系统。最底层的是一个HDFS,是一个分布式的文件系统。但仅有HDFS和Mapreduce还远远不够,很多用户都在上层用一些脚本语言比如PiG、HIVE。现在有些开源系统,比如社交关系网的图形软件,在这些应用的基础上微软加入了JavaScript等。现在微软又加了ODBC,excel、powerview这些现有的微软应用可以访问这些数据。
Windows Azure如何存储数据?
HDFS在Windows Azure上运行,微软已将HDFS的API进行了扩展,使得它可以访问Azure storage和Azure Blob Storage。企业选择大数据平台要尽可能选择廉价的平台。便宜的同时也得保证安全。Azure storage不仅便宜,而且具有三个备份,加上三个异地备份,总共六个备份。
云服务公司不能总说自己产品的可靠性是“99.9999%”。云服务需要绝对的高保证,云服务不仅包括存储硬盘的可靠性,还包括机架、电、网络、bulding等等。“99.9999%”没有任何说服力,徐明强表示,微软Windows Azure从上线至今从未丢过一个字节的数据,Windows Azure不光廉价,而且数据绝对安全。
利用hdfs搭建网盘–webserver开发,描述下实现思路:
1、网盘系统中的webserver是用来给用户提供操作界面,接收用户指令,完成文件上传、下载、图片上传、下载和图片预览功能的。
2、其中关于存储相关的功能都是调用hdfs API来完成,而关于文件的相关结构化信息都存储在mysql关系型数据库中;
3、webserver起到的是连接客户和hdfs的作用
4、采用的是SSH框架(Struts2、spring、hibernate)、数据库为mysql,数据模型请参考:利用hdfs搭建网盘–数据模型设计
5、web调用hdfs API的思路是:利用java运行时 运行java jar包,可参考《利用HDFS java API增删改查操作》,例如:
process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar read "+fileInfo.getFilePath()+" /root/file-tmp/"+fileInfo.getFileName());
文件列表页面:
@Action(value = "right", results = { @Result(name = "success", location = "/WEB-INF/npage/right.jsp") }) public String right() { HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); if (user != null) { page = fileInfoServie.queryUserFileList(0, 20, user.getUserId()); } return "success"; }
文件下载:
@Action(value = "downloadFile", results = { @Result(name = "success", location = "/right", type = "redirectAction") }) public String downloadFile(){ // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); //查出要删除的文件信息 String fileId = getRequest().getParameter("fileId"); List<FileInfo> lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } //路径 String path = "/root/file-tmp/"+fileInfo.getFileName(); // 从hdfs取得文件 Process process; try { process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar read "+fileInfo.getFilePath()+" /root/file-tmp/"+fileInfo.getFileName()); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase(); // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response this.getResponse().reset(); // 设置response的Header this.getResponse().addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); this.getResponse().addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(this.getResponse().getOutputStream()); this.getResponse().setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } return null; }
删除文件:
@Action(value = "deleteFile", results = { @Result(name = "success", location = "/right", type = "redirectAction") }) public String deleteFile(){ // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); //查出要删除的文件信息 String fileId = getRequest().getParameter("fileId"); List<FileInfo> lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } // 将文件从hadoop集群删除 Process process; try { process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar delete "+fileInfo.getFilePath()); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } //从数据库删除 fileInfoServie.deleteById(fileInfo.getId()); return "success"; }
照片列表:
@Action(value = "goPicPage", results = { @Result(name = "success", location = "/WEB-INF/npage/pic-right.jsp") }) public String goPicPage() { HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); if (user != null) { page = fileInfoServie.queryPicFileList(0, 20, user.getUserId()); } return "success"; }
上传文件或者图片:
@Action(value = "uploadFile", results = { @Result(name = "success", location = "/right", type = "redirectAction") }) public String uploadFile() throws IOException { // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); boolean isPic = false; if (file_name.indexOf(".jpg") > 0 || file_name.indexOf(".gif") > 0) { isPic = true; } // 接收文件 String path = ""; if (null != file_name && !file_name.equals("")) { path = fileInfoServie.saveFile(methodFile, file_name); } String fileName = ""; String[] strArr = path.split("/"); if (strArr != null && strArr.length > 0) { fileName = strArr[strArr.length - 1]; } // 将文件上传到hadoop集群 Process process; try { process = Runtime.getRuntime().exec( "java -jar /root/hdfs-0.0.1-SNAPSHOT.jar upload " + path + " hdfs://hadoopm:9000/user/root/upload/" + user.getUserName() + "/" + fileName); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } FileInfo fileInfo = new FileInfo(); fileInfo.setCreateTime(new Date()); fileInfo.setFileName(this.file_name); fileInfo.setFilePath("hdfs://hadoopm:9000/user/root/upload/" + user.getUserName() + "/" + fileName); File fileTemp = new File(path); fileInfo.setFileSize((fileTemp.length() / 1024) > 1 ? (fileTemp.length() / 1024) : 1); //判断是否为图片 if (isPic) { fileInfo.setFileType(1);// 0 :普通文件 1:图片 String tempPath = "/root/" + user.getUserName() + "/"+ System.currentTimeMillis() + "/" + this.file_name; ImageScale.resizeFix(new File(path),new File(tempPath), 250, 250); fileInfo.setImg(tempPath); } else { fileInfo.setFileType(0); } fileInfo.setUserId(user.getUserId()); fileInfo.setFpos(null); fileInfo.setFileId(System.currentTimeMillis()); fileInfoServie.save(fileInfo); return "success"; }
获取缩略图:
@Action(value = "getsImg") public String getsImg() throws IOException { String fileId = getRequest().getParameter("fileId"); List<FileInfo> lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } FileInputStream is = new FileInputStream(fileInfo.getImg()); int i = is.available(); // 得到文件大小 byte data[] = new byte[i]; is.read(data); // 读数据 is.close(); this.getResponse().setContentType("image/*"); // 设置返回的文件类型 OutputStream toClient = this.getResponse().getOutputStream(); // 得到向客户端输出二进制数据的对象 toClient.write(data); // 输出数据 toClient.close(); return null; }
获取大图:
@Action(value = "getbImg") public String getbImg() throws IOException{ // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); //查出要删除的文件信息 String fileId = getRequest().getParameter("fileId"); List<FileInfo> lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } //路径 String path = "/root/file-tmp/bpic/"+fileInfo.getFileName(); // 从hdfs取得文件 Process process; try { process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar read "+fileInfo.getFilePath()+" /root/file-tmp/bpic/"+fileInfo.getFileName()); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } File f = new File(path); if (!f.exists()) { this.getResponse().sendError(404, "File not found!"); return null; } BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0; this.getResponse().reset(); // 非常重要 // 在线打开方式 URL u = new URL("file:///" + path); this.getResponse().setContentType(u.openConnection().getContentType()); this.getResponse().setHeader("Content-Disposition", "inline; filename=" + f.getName()); // 文件名应该编码成UTF-8 OutputStream out = this.getResponse().getOutputStream(); while ((len = br.read(buf)) > 0) out.write(buf, 0, len); br.close(); out.close(); return null; }
完整Action类如下:
package org.nbc.storage.file.action; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.net.URL; import java.util.Date; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.nbc.storage.common.action.BaseAction; import org.nbc.storage.common.util.ImageScale; import org.nbc.storage.file.model.FileInfo; import org.nbc.storage.file.service.FileInfoServie; import org.nbc.storage.user.model.User; import com.sitech.core.orm.PropertyFilter; import com.sitech.core.utils.Page; public class FileAction extends BaseAction { private static final long serialVersionUID = 1L; private Page page; private String file_name; private File methodFile; /** 下载需要的 */ private InputStream inputStream; private String downloadFileName; @Resource public FileInfoServie fileInfoServie; @Action(value = "files", results = { @Result(name = "success", location = "/WEB-INF/npage/main.jsp") }) public String userFileList() { return "success"; } @Action(value = "top", results = { @Result(name = "success", location = "/WEB-INF/npage/top.jsp") }) public String top() { return "success"; } @Action(value = "left", results = { @Result(name = "success", location = "/WEB-INF/npage/left.jsp") }) public String left() { return "success"; } @Action(value = "right_top", results = { @Result(name = "success", location = "/WEB-INF/npage/right_top.jsp") }) public String right_top() { return "success"; } @Action(value = "right", results = { @Result(name = "success", location = "/WEB-INF/npage/right.jsp") }) public String right() { HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); if (user != null) { page = fileInfoServie.queryUserFileList(0, 20, user.getUserId()); } return "success"; } /** * * 下载文件. * * @return */ @Action(value = "downloadFile", results = { @Result(name = "success", location = "/right", type = "redirectAction") }) public String downloadFile(){ // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); //查出要删除的文件信息 String fileId = getRequest().getParameter("fileId"); List lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } //路径 String path = "/root/file-tmp/"+fileInfo.getFileName(); // 从hdfs取得文件 Process process; try { process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar read "+fileInfo.getFilePath()+" /root/file-tmp/"+fileInfo.getFileName()); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase(); // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response this.getResponse().reset(); // 设置response的Header this.getResponse().addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); this.getResponse().addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(this.getResponse().getOutputStream()); this.getResponse().setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } return null; } /** * * 删除文件. * * @return */ @Action(value = "deleteFile", results = { @Result(name = "success", location = "/right", type = "redirectAction") }) public String deleteFile(){ // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); //查出要删除的文件信息 String fileId = getRequest().getParameter("fileId"); List lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } // 将文件从hadoop集群删除 Process process; try { process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar delete "+fileInfo.getFilePath()); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } //从数据库删除 fileInfoServie.deleteById(fileInfo.getId()); return "success"; } @Action(value = "goUploadPage", results = { @Result(name = "success", location = "/WEB-INF/npage/upload-right.jsp") }) public String goUploadPage() { return "success"; } @Action(value = "goPicPage", results = { @Result(name = "success", location = "/WEB-INF/npage/pic-right.jsp") }) public String goPicPage() { HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); if (user != null) { page = fileInfoServie.queryPicFileList(0, 20, user.getUserId()); } return "success"; } /** * * 上传文件或图片. * * @return * @throws IOException */ @Action(value = "uploadFile", results = { @Result(name = "success", location = "/right", type = "redirectAction") }) public String uploadFile() throws IOException { // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); boolean isPic = false; if (file_name.indexOf(".jpg") > 0 || file_name.indexOf(".gif") > 0) { isPic = true; } // 接收文件 String path = ""; if (null != file_name && !file_name.equals("")) { path = fileInfoServie.saveFile(methodFile, file_name); } String fileName = ""; String[] strArr = path.split("/"); if (strArr != null && strArr.length > 0) { fileName = strArr[strArr.length - 1]; } // 将文件上传到hadoop集群 Process process; try { process = Runtime.getRuntime().exec( "java -jar /root/hdfs-0.0.1-SNAPSHOT.jar upload " + path + " hdfs://hadoopm:9000/user/root/upload/" + user.getUserName() + "/" + fileName); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } FileInfo fileInfo = new FileInfo(); fileInfo.setCreateTime(new Date()); fileInfo.setFileName(this.file_name); fileInfo.setFilePath("hdfs://hadoopm:9000/user/root/upload/" + user.getUserName() + "/" + fileName); File fileTemp = new File(path); fileInfo.setFileSize((fileTemp.length() / 1024) > 1 ? (fileTemp.length() / 1024) : 1); //判断是否为图片 if (isPic) { fileInfo.setFileType(1);// 0 :普通文件 1:图片 String tempPath = "/root/" + user.getUserName() + "/"+ System.currentTimeMillis() + "/" + this.file_name; ImageScale.resizeFix(new File(path),new File(tempPath), 250, 250); fileInfo.setImg(tempPath); } else { fileInfo.setFileType(0); } fileInfo.setUserId(user.getUserId()); fileInfo.setFpos(null); fileInfo.setFileId(System.currentTimeMillis()); fileInfoServie.save(fileInfo); return "success"; } /** * * 获取缩略图. * * @return * @throws IOException */ @Action(value = "getsImg") public String getsImg() throws IOException { String fileId = getRequest().getParameter("fileId"); List lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } FileInputStream is = new FileInputStream(fileInfo.getImg()); int i = is.available(); // 得到文件大小 byte data[] = new byte[i]; is.read(data); // 读数据 is.close(); this.getResponse().setContentType("image/*"); // 设置返回的文件类型 OutputStream toClient = this.getResponse().getOutputStream(); // 得到向客户端输出二进制数据的对象 toClient.write(data); // 输出数据 toClient.close(); return null; } /** * * 获取大图. * * @return * @throws IOException */ @Action(value = "getbImg") public String getbImg() throws IOException{ // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); //查出要删除的文件信息 String fileId = getRequest().getParameter("fileId"); List lists = fileInfoServie.findBy("fileId", Long.parseLong(fileId), PropertyFilter.MatchType.EQ); FileInfo fileInfo = new FileInfo(); if(lists != null && lists.size() > 0){ fileInfo = lists.get(0); } //路径 String path = "/root/file-tmp/bpic/"+fileInfo.getFileName(); // 从hdfs取得文件 Process process; try { process = Runtime.getRuntime().exec("java -jar /root/hdfs-0.0.1-SNAPSHOT.jar read "+fileInfo.getFilePath()+" /root/file-tmp/bpic/"+fileInfo.getFileName()); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } File f = new File(path); if (!f.exists()) { this.getResponse().sendError(404, "File not found!"); return null; } BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0; this.getResponse().reset(); // 非常重要 // 在线打开方式 URL u = new URL("file:///" + path); this.getResponse().setContentType(u.openConnection().getContentType()); this.getResponse().setHeader("Content-Disposition", "inline; filename=" + f.getName()); // 文件名应该编码成UTF-8 OutputStream out = this.getResponse().getOutputStream(); while ((len = br.read(buf)) > 0) out.write(buf, 0, len); br.close(); out.close(); return null; } public FileInfoServie getFileInfoServie() { return fileInfoServie; } public void setFileInfoServie(FileInfoServie fileInfoServie) { this.fileInfoServie = fileInfoServie; } public Page getPage() { return page; } public void setPage(Page page) { this.page = page; } public String getFile_name() { return file_name; } public void setFile_name(String file_name) { this.file_name = file_name; } public File getMethodFile() { return methodFile; } public void setMethodFile(File methodFile) { this.methodFile = methodFile; } public String getDownloadFileName() { return downloadFileName; } public void setDownloadFileName(String downloadFileName) { this.downloadFileName = downloadFileName; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } @Action(value = "filelist", results = { @Result(name = "success", location = "/WEB-INF/npage/filelist.jsp") }) public String filelist() { // HttpSession session = this.getRequest().getSession(); // User user = (User) session.getAttribute("user"); // if (user != null) { page = fileInfoServie.queryUserFileList(0, 20, 1L); // } return "success"; } @Action(value = "goUploadPageCC", results = { @Result(name = "success", location = "/WEB-INF/npage/goUploadPageCC.jsp") }) public String goUploadPageCC() { return "success"; } @Action(value = "uploadFileCC", results = { @Result(name = "success", location = "/filelist", type = "redirectAction") }) public String uploadFileCC() throws IOException { // 获取用户信息 HttpSession session = this.getRequest().getSession(); User user = (User) session.getAttribute("user"); boolean isPic = false; if (file_name.indexOf(".jpg") > 0 || file_name.indexOf(".gif") > 0) { isPic = true; } // 接收文件 String path = ""; if (null != file_name && !file_name.equals("")) { path = fileInfoServie.saveFile(methodFile, file_name); } String fileName = ""; String[] strArr = path.split("/"); if (strArr != null && strArr.length > 0) { fileName = strArr[strArr.length - 1]; } // 将文件上传到hadoop集群 Process process; try { process = Runtime.getRuntime().exec( "java -jar /root/hdfs-0.0.1-SNAPSHOT.jar upload " + path + " hdfs://hadoopm:9000/user/root/upload/" + "lisn" + "/" + fileName); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while ((line = input.readLine()) != null) System.out.println(line); } catch (IOException e) { e.printStackTrace(); } FileInfo fileInfo = new FileInfo(); fileInfo.setCreateTime(new Date()); fileInfo.setFileName(this.file_name); fileInfo.setFilePath("hdfs://hadoopm:9000/user/root/upload/" +"lisn" + "/" + fileName); File fileTemp = new File(path); fileInfo.setFileSize((fileTemp.length() / 1024) > 1 ? (fileTemp.length() / 1024) : 1); //判断是否为图片 if (isPic) { fileInfo.setFileType(1);// 0 :普通文件 1:图片 String tempPath = "/root/" + "lisn" + "/"+ System.currentTimeMillis() + "/" + this.file_name; ImageScale.resizeFix(new File(path),new File(tempPath), 250, 250); fileInfo.setImg(tempPath); } else { fileInfo.setFileType(0); } fileInfo.setUserId(1L); fileInfo.setFpos(null); fileInfo.setFileId(System.currentTimeMillis()); fileInfoServie.save(fileInfo); return "success"; } }
完整services:
package org.nbc.storage.file.service.impl; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import javax.annotation.Resource; import org.nbc.storage.file.model.FileInfo; import org.nbc.storage.file.service.FileInfoServie; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.sitech.core.orm.BaseDAO; import com.sitech.core.service.impl.BaseServiceImpl; import com.sitech.core.utils.Page; @Service("fileInfoServie") @Transactional public class FileInfoServieImpl extends BaseServiceImpl<FileInfo, Long> implements FileInfoServie { private static int BUFFER_SIZE = 16 * 1024; @Resource(name = "fileInfoDAO") public void setBaseDAO(BaseDAO<FileInfo, Long> baseDAO) { super.setBaseDAO(baseDAO); } @Override public Page<FileInfo> queryUserFileList(int pageNo, int pageSize, Long userId) { String hql = " from FileInfo where userId = ? order by createTime desc "; Page<FileInfo> page = new Page<FileInfo>(pageSize); page.setPageNo(pageNo); return this.getBaseDAO().findPage(page, hql, userId); } public long copyFile(File src, File dest) throws Exception { BufferedInputStream in = null; BufferedOutputStream out = null; byte[] buffer = new byte[BUFFER_SIZE]; long total = 0; try { in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE); out = new BufferedOutputStream(new FileOutputStream(dest), BUFFER_SIZE); int curSize = in.read(buffer); while (curSize > 0) { total += curSize; out.write(buffer, 0, curSize); curSize = in.read(buffer); } } catch (Exception e) { } finally { try { if (in != null) { in.close(); in = null; } if (out != null) { out.close(); out = null; } } catch (Exception e) { e.printStackTrace(); } } return total; } public String saveFile(File methodFile,String file_name){ String savePath = "/root/lisn/"; String middlePath = ""; String separator = "/"; String [] strArr = file_name.split("\."); if(strArr != null && strArr.length > 0){ file_name = strArr[strArr.length-1]; } //创建filename file_name = System.currentTimeMillis() + "."+file_name; File f = new File(savePath); if (!f.exists()) { f.mkdirs(); } File file = new File(savePath+file_name); try { file.createNewFile(); long total = copyFile(methodFile, file); } catch (Exception e) { e.printStackTrace(); } return savePath+file_name; } @Override public Page<FileInfo> queryPicFileList(int pageNo, int pageSize, Long userId) { String hql = " from FileInfo where userId = ? and fileType = 1 order by createTime desc "; Page<FileInfo> page = new Page<FileInfo>(pageSize); page.setPageNo(pageNo); return this.getBaseDAO().findPage(page, hql, userId); } }
展示图片预览页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> <!-- .STYLE1 {font-size: 12px} .STYLE3 {color: #707070; font-size: 12px; } .STYLE5 {color: #0a6e0c; font-size: 12px; } body { margin-top: 0px; margin-bottom: 0px; } .STYLE7 {font-size: 12} --> </style> </head> <body> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td height="30"><table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> </td> <td style="padding-right:10px;"><div align="right"> <table border="0" align="right" cellpadding="0" cellspacing="0"> <tr> <td width="60"><table width="87%" border="0" cellpadding="0" cellspacing="0"> <tr> <!-- <td class="STYLE1"><div align="center"> <input type="checkbox" name="checkbox62" value="checkbox" /> </div></td>--> <td class="STYLE1" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/goPicPage'"><div align="center" style="cursor:pointer;">图片列表</div></td> </tr> </table></td> <td width="60"><table width="90%" border="0" cellpadding="0" cellspacing="0"> <tr> <!-- <td class="STYLE1"><div align="center"><img src="<%=request.getContextPath() %>/images/001.gif" width="14" height="14" /></div></td> --> <td class="STYLE1" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/goUploadPage'"><div align="center" style="cursor:pointer;">上传文件</div></td> </tr> </table></td> <td width="60"><table width="90%" border="0" cellpadding="0" cellspacing="0"> <tr> <!-- <td class="STYLE1"><div align="center"><img src="<%=request.getContextPath() %>/images/114.gif" width="14" height="14" /></div></td> --> <td class="STYLE1" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/right'"><div align="center" style="cursor:pointer;">文件列表</div></td> </tr> </table></td> <!-- <td width="52"><table width="88%" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="STYLE1"><div align="center"><img src="<%=request.getContextPath() %>/images/083.gif" width="14" height="14" /></div></td> <td class="STYLE1"><div align="center">删除</div></td> </tr> </table></td> --> </tr> </table> </div></td> </tr> </table></td> </tr> <tr> <td><table width="100%" border="0" cellpadding="0" cellspacing="1" bgcolor="#c9c9c9"> <tr> <td height="22" bgcolor="#FFFFFF" width="50%"><div align="center"><strong><span class="STYLE1">图片预览</span></strong></div></td> </tr> <s:iterator value="page.result" var="file"> <tr> <td height="22" bgcolor="#FFFFFF" width="50%"><div align="center"><span class="STYLE3" style="cursor:pointer;"><img onclick="window.open('http://192.168.75.142:8080/wangpan-web/getbImg?fileId=<s:property value="fileId" />');" title="点击查看大图" alt="<s:property value="fileName" />" src="http://192.168.75.142:8080/wangpan-web/getsImg?fileId=<s:property value="fileId" />" > </span></div></td> </tr> </s:iterator> </table></td> </tr> <tr> <td height="35"><table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="25%" height="29" nowrap="nowrap"><table width="342" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="44%" class="STYLE1">当前页:1/2页 每页 <input name="textfield2" type="text" class="STYLE1" style="height:14px; width:25px;" value="15" size="5" /> </td> <td width="14%" class="STYLE1"><img src="<%=request.getContextPath() %>/images/sz.gif" width="43" height="20" /></td> <td width="42%" class="STYLE1"><span class="STYLE7">数据总量 15 </span></td> </tr> </table></td> <td width="75%" valign="top" class="STYLE1"><div align="right"> <table width="352" height="20" border="0" cellpadding="0" cellspacing="0"> <tr> <td width="62" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_first_1.gif" width="48" height="20" /></div></td> <td width="50" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_back_1.gif" width="55" height="20" /></div></td> <td width="54" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_next.gif" width="58" height="20" /></div></td> <td width="49" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_last.gif" width="52" height="20" /></div></td> <td width="59" height="22" valign="middle"><div align="right">转到第</div></td> <td width="25" height="22" valign="middle"><span class="STYLE7"> <input name="textfield" type="text" class="STYLE1" style="height:10px; width:25px;" size="5" /> </span></td> <td width="23" height="22" valign="middle">页</td> <td width="30" height="22" valign="middle"><img src="<%=request.getContextPath() %>/images/go.gif" width="26" height="20" /></td> </tr> </table> </div></td> </tr> </table></td> </tr> </table> </body> </html>
文件列表页:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> <!-- .STYLE1 {font-size: 12px} .STYLE3 {color: #707070; font-size: 12px; } .STYLE5 {color: #0a6e0c; font-size: 12px; } body { margin-top: 0px; margin-bottom: 0px; } .STYLE7 {font-size: 12} --> </style> </head> <body> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td height="30"><table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> </td> <td style="padding-right:10px;"><div align="right"> <table border="0" align="right" cellpadding="0" cellspacing="0"> <tr> <td width="60"><table width="87%" border="0" cellpadding="0" cellspacing="0"> <tr> <!-- <td class="STYLE1"><div align="center"> <input type="checkbox" name="checkbox62" value="checkbox" /> </div></td>--> <td class="STYLE1" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/goPicPage'"><div align="center" style="cursor:pointer;">图片列表</div></td> </tr> </table></td> <td width="60"><table width="90%" border="0" cellpadding="0" cellspacing="0"> <tr> <!-- <td class="STYLE1"><div align="center"><img src="<%=request.getContextPath() %>/images/001.gif" width="14" height="14" /></div></td> --> <td class="STYLE1" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/goUploadPage'"><div align="center" style="cursor:pointer;">上传文件</div></td> </tr> </table></td> <td width="60"><table width="90%" border="0" cellpadding="0" cellspacing="0"> <tr> <!-- <td class="STYLE1"><div align="center"><img src="<%=request.getContextPath() %>/images/114.gif" width="14" height="14" /></div></td> --> <td class="STYLE1" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/right'"><div align="center" style="cursor:pointer;">文件列表</div></td> </tr> </table></td> <!-- <td width="52"><table width="88%" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="STYLE1"><div align="center"><img src="<%=request.getContextPath() %>/images/083.gif" width="14" height="14" /></div></td> <td class="STYLE1"><div align="center">删除</div></td> </tr> </table></td> --> </tr> </table> </div></td> </tr> </table></td> </tr> <tr> <td><table width="100%" border="0" cellpadding="0" cellspacing="1" bgcolor="#c9c9c9"> <tr> <td height="22" bgcolor="#FFFFFF" width="50%"><div align="center"><strong><span class="STYLE1">文件名</span></strong></div></td> <td height="22" bgcolor="#FFFFFF"><div align="center"><strong><span class="STYLE1">大小</span></strong></div></td> <td height="22" bgcolor="#FFFFFF"><div align="center"><strong><span class="STYLE1">上传日期</span></strong></div></td> <td height="22" bgcolor="#FFFFFF"><div align="center"><strong><span class="STYLE1">操作</span></strong></div></td> </tr> <s:iterator value="page.result" var="file"> <tr> <td height="22" bgcolor="#FFFFFF" width="50%"><div align="center"><span class="STYLE3"><s:property value="fileName" /></span></div></td> <td height="22" bgcolor="#FFFFFF"><div align="center"><span class="STYLE3"><s:property value="fileSize" /> KB</span></div></td> <td height="22" bgcolor="#FFFFFF"><div align="center"><span class="STYLE3"><s:date name="createTime" format="yyyy-MM-dd HH:mm" /></span></div></td> <td height="22" bgcolor="#FFFFFF"> <div align="center"> <span style="cursor:pointer;" class="STYLE3" onclick="window.location.href='<%=request.getContextPath() %>/wangpan-web/deleteFile?fileId=<s:property value="fileId" />'">删除</span> <span style="cursor:pointer;" class="STYLE3" onclick="window.open('<%=request.getContextPath() %>/wangpan-web/downloadFile?fileId=<s:property value="fileId" />');">下载</span> </div> </td> </tr> </s:iterator> </table></td> </tr> <tr> <td height="35"><table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="25%" height="29" nowrap="nowrap"><table width="342" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="44%" class="STYLE1">当前页:1/2页 每页 <input name="textfield2" type="text" class="STYLE1" style="height:14px; width:25px;" value="15" size="5" /> </td> <td width="14%" class="STYLE1"><img src="<%=request.getContextPath() %>/images/sz.gif" width="43" height="20" /></td> <td width="42%" class="STYLE1"><span class="STYLE7">数据总量 15 </span></td> </tr> </table></td> <td width="75%" valign="top" class="STYLE1"><div align="right"> <table width="352" height="20" border="0" cellpadding="0" cellspacing="0"> <tr> <td width="62" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_first_1.gif" width="48" height="20" /></div></td> <td width="50" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_back_1.gif" width="55" height="20" /></div></td> <td width="54" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_next.gif" width="58" height="20" /></div></td> <td width="49" height="22" valign="middle"><div align="right"><img src="<%=request.getContextPath() %>/images/page_last.gif" width="52" height="20" /></div></td> <td width="59" height="22" valign="middle"><div align="right">转到第</div></td> <td width="25" height="22" valign="middle"><span class="STYLE7"> <input name="textfield" type="text" class="STYLE1" style="height:10px; width:25px;" size="5" /> </span></td> <td width="23" height="22" valign="middle">页</td> <td width="30" height="22" valign="middle"><img src="<%=request.getContextPath() %>/images/go.gif" width="26" height="20" /></td> </tr> </table> </div></td> </tr> </table></td> </tr> </table> </body> </html>
1、阿里神话,阿里将数据一致性高的都放在银行侧了,这是他们去ioe化的基础,并且,马云可以选择哪家银行存放钱,这是阿里的底气。在双十一阿里显得霸气侧漏的时候,其实苦逼的是银行。
2、数据中心进了老鼠怎么办,谷歌不知道怎么办,但国内银行是放只猫,抓完老鼠就拿出来。
3、企业IT和互联网IT,如果在某一方面达到极致,那么最后都是相通的,我随不做你那方面的东西,但我一眼就能看出来,哪些地方是夸大,哪些是创新。
4、对数据一致性要求高的一定是用IOE的,这是架构设计的选型依据。
上课感想(观点不一定正确),后续补充….
相关资料:
(1)、IOE事件中的I是代表IBM的缩写,也即去IBM的存储设备和小型机,主要是小型机,阿里巴巴、淘宝和支付宝主要是使用了IBM的小型机,IBM存储设备相对较少;
(2)、IOE 事件中的O是代表Oracle的缩写,也即去处Oracle数据库,采用MySQL和Hadoop替代的解决方案,Oracle RAC将会被Hadoop集群替代,其阿里巴巴B2B使用的GreenPlum集群,也将会在阿里巴巴集团完成运维团队和DBA团队合并之后,采用 Hadoop集群解决方案替代;
(3)、IOE事件中的E是代表EMC2,阿里巴巴B2B、淘宝和支付宝都是用大量EMC2的存储设备,也有少量DELL的存储设备,主要是EMC2,的存储设备性价比高;
(4)、阿里巴巴集团内部最早进行MySQL数据库替代Oracle数据库支持数据服务的子公司,是阿里巴巴B2B用PC Server替代EMC2,存储设备,替代IBM小型机。不过替换节凑是被合理控制的,因多方面的原因内部也没有那么雄壮的决心。后来,淘宝也开始进行MySQL数据库的应用摸索和推广,并且高调宣传去IOE事件,最后造成网络上满城风雨;
今天碰到一个诡异的问题,线上系统没有问题可以访问,但在本机测试却不行。现象是在火狐访问空白页面,当时就蒙了啊,后来换ie则提示:400 Bad Request。
原来url中不允许出现特殊字符,比如:%
修改前url:http://index.youku.com/vr_keyword/id_6ZOB6KGA5L2%2f5ZG9&type=alldata
修改后url:http://index.youku.com/vr_keyword/id_6ZOB6KGA5L2%2f5ZG9&type=alldata
修改前代码:
var reg = new RegExp("\+", "g"); // 创建正则RegExp对象 var reg2 = new RegExp("\=", "g"); var reg3 = new RegExp("\/", "g"); basewords = basewords.replace(reg, "%2b"); basewords = basewords.replace(reg2, "%3d"); basewords = basewords.replace(reg3, "%2f");
修改后的代码:
var reg = new RegExp("\+", "g"); // 创建正则RegExp对象 var reg2 = new RegExp("\=", "g"); var reg3 = new RegExp("\/", "g"); basewords = basewords.replace(reg, "%252b"); basewords = basewords.replace(reg2, "%253d"); basewords = basewords.replace(reg3, "%252f");
PS:修改前url在线上是没有问题的,使用的resin服务器,但本机开发的tomcat却无法通过!估计处理机制有区别!
有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号。 编码的格式为:%加对应字符的ASCII(16进制)码值。例如:空格的编码值是”%20″ 。
一些URL特殊符号及编码(十六进制值)
1. + URL中+号表示空格 %2B
2. 空格 URL中的空格可以用+号或者编码 %20
3. / 分隔目录和子目录 %2F
4. ? 分隔实际的 URL 和参数 %3F
5. % 指定特殊字符 %25
6. # 表示书签 %23
7. & URL中指定的参数间的分隔符 %26
8. = URL中指定参数的值 %3D
java中URL的编码和解码函数: java.net.URLEncoder.encode(String s) java.net.URLDecoder.decode(String s);
javascript中URL的编码和解码函数: escape(String s) unescape(String s) ;
更详细资料:
http://www.cnblogs.com/leaven/archive/2012/07/12/2588746.html