├── .classpath ├── .gitignore ├── .project ├── .settings ├── .jsdtscope ├── org.eclipse.jdt.core.prefs ├── org.eclipse.wst.common.component ├── org.eclipse.wst.common.project.facet.core.xml ├── org.eclipse.wst.jsdt.ui.superType.container └── org.eclipse.wst.jsdt.ui.superType.name ├── LICENSE ├── README.md ├── WebContent ├── META-INF │ └── MANIFEST.MF ├── WEB-INF │ └── web.xml └── upload │ ├── fileupload.jsp │ └── uploadresult.jsp ├── build └── classes │ └── .gitignore └── src └── com ├── hotpatch ├── DefaultPatch.java ├── IPatch.java └── PatchInfo.java └── server └── fileupload ├── FileUpLoad.java ├── Patch.java └── Test.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | PathServer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.jsdt.core.javascriptValidator 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.common.project.facet.core.builder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.validation.validationbuilder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.jem.workbench.JavaEMFNature 31 | org.eclipse.wst.common.modulecore.ModuleCoreNature 32 | org.eclipse.wst.common.project.facet.core.nature 33 | org.eclipse.jdt.core.javanature 34 | org.eclipse.wst.jsdt.core.jsNature 35 | 36 | 37 | -------------------------------------------------------------------------------- /.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.8 8 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 feng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hotpatch-SimpleServer 2 | The server for hotpatch,simple implment. 3 | -------------------------------------------------------------------------------- /WebContent/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PathServer 4 | 5 | /upload/fileupload.jsp 6 | 7 | 8 | FileUpLoad 9 | com.server.fileupload.FileUpLoad 10 | 11 | 12 | FileUpLoad 13 | /FileUpLoad 14 | 15 | 16 | 17 | Test 18 | com.server.fileupload.Test 19 | 20 | 21 | Test 22 | /Test 23 | 24 | 25 | 26 | Patch 27 | com.server.fileupload.Patch 28 | 29 | 30 | Patch 31 | /patch 32 | 33 | -------------------------------------------------------------------------------- /WebContent/upload/fileupload.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <% 3 | String path = request.getContextPath(); 4 | String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 | %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | My JSP 'fileupload.jsp' starting page 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 被patch apk最低版本号:
30 | 被patch apk最高版本号:
31 | upload Patch apk:
32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /WebContent/upload/uploadresult.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <% 3 | String path = request.getContextPath(); 4 | String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 | %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | My JSP 'filedemo.jsp' starting page 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | patch apk最低版本号:${requestScope.minApkVersion }
28 | patch apk最高版本号:${requestScope.maxApkVersion }
29 | 文件:${requestScope.file1 }
30 | ${requestScope.md5}
31 | 32 | ">文件下载地址 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /build/classes/.gitignore: -------------------------------------------------------------------------------- 1 | /com/ 2 | -------------------------------------------------------------------------------- /src/com/hotpatch/DefaultPatch.java: -------------------------------------------------------------------------------- 1 | package com.hotpatch; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import com.alibaba.fastjson.JSON; 10 | import com.server.fileupload.FileUpLoad; 11 | 12 | public class DefaultPatch implements IPatch { 13 | 14 | 15 | @Override 16 | public void getPatchInfo(HttpServletRequest request,HttpServletResponse resp) { 17 | PatchInfo info=new PatchInfo(); 18 | String path = request.getRealPath("/upload"); 19 | //String version=request.getAttribute("version").toString(); 20 | File file=new File(path,"app-debug.apk"); 21 | String md5=FileUpLoad.getMd5ByFile(file); 22 | info.md5=md5; 23 | //please change the url to your service ip address 24 | info.patchApkUrl="http://192.168.0.100:8080/PathServer/upload/app-debug.apk"; 25 | 26 | String text=JSON.toJSONString(info); 27 | try { 28 | resp.getWriter().write(text); 29 | resp.getWriter().close(); 30 | } catch (IOException e) { 31 | // TODO Auto-generated catch block 32 | e.printStackTrace(); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/com/hotpatch/IPatch.java: -------------------------------------------------------------------------------- 1 | package com.hotpatch; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | public interface IPatch { 7 | void getPatchInfo(HttpServletRequest req ,HttpServletResponse resp); 8 | } 9 | -------------------------------------------------------------------------------- /src/com/hotpatch/PatchInfo.java: -------------------------------------------------------------------------------- 1 | package com.hotpatch; 2 | 3 | public class PatchInfo { 4 | public String md5; 5 | public String patchApkUrl; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/com/server/fileupload/FileUpLoad.java: -------------------------------------------------------------------------------- 1 | package com.server.fileupload; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | import java.math.BigInteger; 10 | import java.nio.MappedByteBuffer; 11 | import java.nio.channels.FileChannel; 12 | import java.security.MessageDigest; 13 | import java.util.List; 14 | 15 | import javax.servlet.ServletException; 16 | import javax.servlet.http.HttpServlet; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | 20 | import org.apache.commons.fileupload.FileItem; 21 | import org.apache.commons.fileupload.FileUploadException; 22 | import org.apache.commons.fileupload.disk.DiskFileItemFactory; 23 | import org.apache.commons.fileupload.servlet.ServletFileUpload; 24 | 25 | /** 26 | * 27 | * @author Administrator 文件上传 具体步骤: 1)获得磁盘文件条目工厂 DiskFileItemFactory 要导包 2) 利用 28 | * request 获取 真实路径 ,供临时文件存储,和 最终文件存储 ,这两个存储位置可不同,也可相同 3)对 29 | * DiskFileItemFactory 对象设置一些 属性 4)高水平的API文件上传处理 ServletFileUpload 30 | * upload = new ServletFileUpload(factory); 目的是调用 31 | * parseRequest(request)方法 获得 FileItem 集合list , 32 | * 33 | * 5)在 FileItem 对象中 获取信息, 遍历, 判断 表单提交过来的信息 是否是 普通文本信息 另做处理 6) 第一种. 用第三方 34 | * 提供的 item.write( new File(path,filename) ); 直接写到磁盘上 第二种. 手动处理 35 | * 36 | */ 37 | public class FileUpLoad extends HttpServlet { 38 | 39 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 40 | 41 | request.setCharacterEncoding("utf-8"); // 设置编码 42 | System.out.println("start post"); 43 | // 获得磁盘文件条目工厂 44 | DiskFileItemFactory factory = new DiskFileItemFactory(); 45 | // 获取文件需要上传到的路径 46 | String path = request.getRealPath("/upload"); 47 | 48 | // 如果没以下两行设置的话,上传大的 文件 会占用 很多内存, 49 | // 设置暂时存放的 存储室 , 这个存储室,可以和 最终存储文件 的目录不同 50 | /** 51 | * 原理 它是先存到 暂时存储室,然后在真正写到 对应目录的硬盘上, 按理来说 当上传一个文件时,其实是上传了两份,第一个是以 .tem 52 | * 格式的 然后再将其真正写到 对应目录的硬盘上 53 | */ 54 | factory.setRepository(new File(path)); 55 | // 设置 缓存的大小,当上传文件的容量超过该缓存时,直接放到 暂时存储室 56 | factory.setSizeThreshold(1024 * 1024); 57 | 58 | // 高水平的API文件上传处理 59 | ServletFileUpload upload = new ServletFileUpload(factory); 60 | 61 | try { 62 | // 可以上传多个文件 63 | List list = (List) upload.parseRequest(request); 64 | 65 | for (FileItem item : list) { 66 | // 获取表单的属性名字 67 | String name = item.getFieldName(); 68 | 69 | // 如果获取的 表单信息是普通的 文本 信息 70 | if (item.isFormField()) { 71 | // 获取用户具体输入的字符串 ,名字起得挺好,因为表单提交过来的是 字符串类型的 72 | String value = item.getString(); 73 | 74 | request.setAttribute(name, value); 75 | } 76 | // 对传入的非 简单的字符串进行处理 ,比如说二进制的 图片,电影这些 77 | else { 78 | /** 79 | * 以下三步,主要获取 上传文件的名字 80 | */ 81 | // 获取路径名 82 | String value = item.getName(); 83 | // 索引到最后一个反斜杠 84 | int start = value.lastIndexOf("\\"); 85 | // 截取 上传文件的 字符串名字,加1是 去掉反斜杠, 86 | String filename = value.substring(start + 1); 87 | 88 | request.setAttribute(name, filename); 89 | 90 | // 真正写到磁盘上 91 | // 它抛出的异常 用exception 捕捉 92 | 93 | // item.write( new File(path,filename) );//第三方提供的 94 | 95 | // 手动写的 96 | File file=new File(path, filename); 97 | OutputStream out = new FileOutputStream(file); 98 | 99 | InputStream in = item.getInputStream(); 100 | 101 | int length = 0; 102 | byte[] buf = new byte[1024]; 103 | 104 | System.out.println("获取上传文件的总共的容量:" + item.getSize()); 105 | 106 | // in.read(buf) 每次读到的数据存放在 buf 数组中 107 | while ((length = in.read(buf)) != -1) { 108 | // 在 buf 数组中 取出数据 写到 (输出流)磁盘上 109 | out.write(buf, 0, length); 110 | 111 | } 112 | 113 | in.close(); 114 | out.close(); 115 | 116 | String md5=getMd5ByFile(file); 117 | request.setAttribute("md5", md5); 118 | System.out.println("md5:"+md5); 119 | } 120 | } 121 | 122 | } catch (FileUploadException e) { 123 | // TODO Auto-generated catch block 124 | e.printStackTrace(); 125 | } catch (Exception e) { 126 | // TODO Auto-generated catch block 127 | 128 | // e.printStackTrace(); 129 | } 130 | 131 | request.getRequestDispatcher("/upload/uploadresult.jsp").forward(request, response); 132 | 133 | } 134 | public static String getMd5ByFile(File file) { 135 | String value = null; 136 | FileInputStream in=null; 137 | try { 138 | in = new FileInputStream(file); 139 | MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 140 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 141 | md5.update(byteBuffer); 142 | BigInteger bi = new BigInteger(1, md5.digest()); 143 | value = bi.toString(16); 144 | } catch (Exception e) { 145 | e.printStackTrace(); 146 | } finally { 147 | if (null != in) { 148 | try { 149 | in.close(); 150 | } catch (IOException e) { 151 | e.printStackTrace(); 152 | } 153 | } 154 | } 155 | return value; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/com/server/fileupload/Patch.java: -------------------------------------------------------------------------------- 1 | package com.server.fileupload; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | import com.hotpatch.DefaultPatch; 11 | 12 | public class Patch extends HttpServlet { 13 | 14 | @Override 15 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 16 | new DefaultPatch().getPatchInfo(req, resp); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/server/fileupload/Test.java: -------------------------------------------------------------------------------- 1 | package com.server.fileupload; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | import java.util.List; 9 | 10 | import javax.servlet.ServletException; 11 | import javax.servlet.http.HttpServlet; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | 15 | import org.apache.commons.fileupload.FileItem; 16 | import org.apache.commons.fileupload.FileUploadException; 17 | import org.apache.commons.fileupload.disk.DiskFileItemFactory; 18 | import org.apache.commons.fileupload.servlet.ServletFileUpload; 19 | 20 | public class Test extends HttpServlet { 21 | 22 | @Override 23 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 24 | resp.setContentType("text/html"); 25 | resp.getWriter().write("hello wrold"); 26 | } 27 | 28 | 29 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 30 | 31 | request.setCharacterEncoding("utf-8"); // 设置编码 32 | System.out.println("start post"); 33 | // 获得磁盘文件条目工厂 34 | DiskFileItemFactory factory = new DiskFileItemFactory(); 35 | // 获取文件需要上传到的路径 36 | String path = request.getRealPath("/upload"); 37 | 38 | // 如果没以下两行设置的话,上传大的 文件 会占用 很多内存, 39 | // 设置暂时存放的 存储室 , 这个存储室,可以和 最终存储文件 的目录不同 40 | /** 41 | * 原理 它是先存到 暂时存储室,然后在真正写到 对应目录的硬盘上, 按理来说 当上传一个文件时,其实是上传了两份,第一个是以 .tem 42 | * 格式的 然后再将其真正写到 对应目录的硬盘上 43 | */ 44 | factory.setRepository(new File(path)); 45 | // 设置 缓存的大小,当上传文件的容量超过该缓存时,直接放到 暂时存储室 46 | factory.setSizeThreshold(1024 * 1024); 47 | 48 | // 高水平的API文件上传处理 49 | ServletFileUpload upload = new ServletFileUpload(factory); 50 | 51 | try { 52 | // 可以上传多个文件 53 | List list = (List) upload.parseRequest(request); 54 | 55 | for (FileItem item : list) { 56 | // 获取表单的属性名字 57 | String name = item.getFieldName(); 58 | 59 | // 如果获取的 表单信息是普通的 文本 信息 60 | if (item.isFormField()) { 61 | // 获取用户具体输入的字符串 ,名字起得挺好,因为表单提交过来的是 字符串类型的 62 | String value = item.getString(); 63 | 64 | request.setAttribute(name, value); 65 | } 66 | // 对传入的非 简单的字符串进行处理 ,比如说二进制的 图片,电影这些 67 | else { 68 | /** 69 | * 以下三步,主要获取 上传文件的名字 70 | */ 71 | // 获取路径名 72 | String value = item.getName(); 73 | // 索引到最后一个反斜杠 74 | int start = value.lastIndexOf("\\"); 75 | // 截取 上传文件的 字符串名字,加1是 去掉反斜杠, 76 | String filename = value.substring(start + 1); 77 | 78 | request.setAttribute(name, filename); 79 | 80 | // 真正写到磁盘上 81 | // 它抛出的异常 用exception 捕捉 82 | 83 | // item.write( new File(path,filename) );//第三方提供的 84 | 85 | // 手动写的 86 | OutputStream out = new FileOutputStream(new File(path, filename)); 87 | 88 | InputStream in = item.getInputStream(); 89 | 90 | int length = 0; 91 | byte[] buf = new byte[1024]; 92 | 93 | System.out.println("获取上传文件的总共的容量:" + item.getSize()); 94 | 95 | // in.read(buf) 每次读到的数据存放在 buf 数组中 96 | while ((length = in.read(buf)) != -1) { 97 | // 在 buf 数组中 取出数据 写到 (输出流)磁盘上 98 | out.write(buf, 0, length); 99 | 100 | } 101 | 102 | in.close(); 103 | out.close(); 104 | } 105 | } 106 | 107 | } catch (FileUploadException e) { 108 | // TODO Auto-generated catch block 109 | e.printStackTrace(); 110 | } catch (Exception e) { 111 | // TODO Auto-generated catch block 112 | 113 | // e.printStackTrace(); 114 | } 115 | 116 | request.getRequestDispatcher("/upload/uploadresult.jsp").forward(request, response); 117 | 118 | } 119 | 120 | 121 | 122 | } 123 | --------------------------------------------------------------------------------