关键业务
添加一个新版本,默认是关闭发布的状态,如果填写的内容有误,可以进行修改删除
发布版本是很严谨的,一旦发布版本,就不能关闭
app端点击更新按钮时, 更新到已发布版本的最新版
CREATE TABLE `tb_version` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`version` varchar(50) DEFAULT NULL COMMENT '版本号',
`picture_path` text COMMENT '图片路径',
`download_path` text COMMENT '更新包地址',
`download_type` int(2) DEFAULT NULL COMMENT '下载地址的类型 1上传应用 2填写外部链接',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`release_time` datetime DEFAULT NULL COMMENT '发布时间',
`is_release` int(2) DEFAULT NULL COMMENT '是否发布 0关闭 1开启',
`is_delete` int(2) DEFAULT '0' COMMENT '是否删除 1删除 0未删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `index_version` (`version`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='版本信息';
CREATE TABLE `tb_version_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`version_id` bigint(20) NOT NULL COMMENT '版本ID',
`introduction` varchar(255) DEFAULT NULL COMMENT '版本内容',
`order_num` int(11) DEFAULT NULL COMMENT '顺序号',
`is_delete` int(2) DEFAULT '0' COMMENT '是否删除 1删除 0未删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='版本详情';
后台管理系统
VersionController.java
import com.yymt.common.annotation.Login;
import com.yymt.common.constants.VersionConstant;
import com.yymt.common.utils.BigDataUtil;
import com.yymt.common.utils.ConvertUtil;
import com.yymt.common.utils.R;
import com.yymt.dao.sys.VersionInfoDao;
import com.yymt.entity.sys.VersionEntity;
import com.yymt.modules.controller.base.BaseController;
import com.yymt.service.sys.VersionInfoService;
import com.yymt.service.sys.VersionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 版本信息
*/
@RestController
@RequestMapping("version")
@Api(tags = "版本信息")
public class VersionController extends BaseController {
@Autowired
private VersionService versionService;
@Autowired
private VersionInfoService versionInfoService;
@Autowired
VersionInfoDao versionInfoDao;
@PostMapping("/save")
@ApiOperation(value = "保存")
@Login
public R save(
@ApiParam("参数说明 " +
"version:版本号,introduction:更新内容(必须传数组格式),picturePath:图片路径(必须传数组格式), " +
"downloadPath:下载链接, downloadType:下载链接的类型(1上传应用 2填写外部链接)")
@RequestBody Map<String, Object> params) {
return versionService.saveData(params);
}
@PostMapping("/updateReleaseStatus/{id}")
@ApiOperation(value = "开启发布")
@Login
public R updateReleaseStatus(@PathVariable("id") Long id){
VersionEntity versionEntity = versionService.selectById(id);
if (versionEntity == null) {
return R.error("该版本不存在");
}
if (VersionConstant.VERSION_RELEASE_OPEN == versionEntity.getIsRelease()) {
return R.error("已发布版本不能关闭!!");
}
versionEntity.setIsRelease(VersionConstant.VERSION_RELEASE_OPEN);
versionEntity.setReleaseTime(new Date());
versionService.updateById(versionEntity);
return R.ok();
}
@PostMapping("/list")
@ApiOperation(value = "列表")
@Login
public R list(
@ApiParam(value = "参数说明 titleKeyword:关键词,pageSize:个数,currPage:当前页")
@RequestBody Map<String, Object> params) {
return versionService.queryPageData(params, getTopUrl());
}
@PostMapping("/info/{id}")
@ApiOperation(value = "信息")
@Login
public R info(@PathVariable("id") Long id){
VersionEntity version = versionService.selectById(id);
if (version == null) {
return R.error("该数据不存在");
}
return versionService.selectInfo(id, getTopUrl());
}
@PostMapping("/update")
@ApiOperation(value = "修改")
@Login
public R update(
@ApiParam("参数说明 " +
"version:版本号,introduction:更新内容(必须传数组格式),picturePath:图片路径(必须传数组格式), " +
"downloadPath:下载链接, downloadType:下载链接的类型(1上传应用 2填写外部链接),id:版本ID(必填)")
@RequestBody Map<String, Object> params) {
Long id = ConvertUtil.parseLong(params.get("id"));
VersionEntity versionEntity = versionService.selectById(id);
if (versionEntity == null) {
return R.error("id不能为空或者该id不存在");
}
// ###### 先删除, 后添加 #######
versionService.deleteById(id);
// 获取当前版本的所有版本更新内容
List<Map<String, Object>> list = versionInfoDao.queryDataByVersionId(id);
// 获取所有id
List idList = BigDataUtil.getColumnValueToList(list, "id", 0);
versionInfoService.deleteBatchIds(idList);
return versionService.saveData(params);
}
@PostMapping("/delete/{id}")
@ApiOperation(value = "删除")
@Login
public R delete(@PathVariable("id") Long id){
// 这里用物理删除, 不用逻辑删除, 避免版本号被占用
versionService.deleteById(id);
return R.ok();
}
}
VersionService .java
import com.baomidou.mybatisplus.service.IService;
import com.yymt.common.utils.PageUtils;
import com.yymt.common.utils.R;
import com.yymt.entity.sys.VersionEntity;
import java.util.List;
import java.util.Map;
/**
* 版本信息
*/
public interface VersionService extends IService<VersionEntity> {
PageUtils queryPage(Map<String, Object> params);
/**
* @Description: 最新版本信息
*/
List<Map<String, Object>> selectLastInfo();
/**
* @Description: 保存
*/
R saveData(Map<String, Object> params);
/**
* @Description: 列表
*/
R queryPageData(Map<String, Object> params, String topUrl);
/**
* @Description: 获取总记录数
*/
int queryCountData(Map<String, Object> params);
/**
* @Description: 信息
*/
R selectInfo(Long id, String topUrl);
/**
* @Description: 删除/批量删除
*/
R deleteData(List idList);
/**
* @Description: 当前版本信息
*/
List<Map<String, Object>> selectCurrentInfoByVersion(Map<String, Object> params);
}
VersionServiceImpl.java
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yymt.common.constants.DeleteSymble;
import com.yymt.common.constants.VersionConstant;
import com.yymt.common.utils.*;
import com.yymt.dao.sys.VersionDao;
import com.yymt.dao.sys.VersionInfoDao;
import com.yymt.entity.sys.VersionEntity;
import com.yymt.entity.sys.VersionInfoEntity;
import com.yymt.service.sys.VersionInfoService;
import com.yymt.service.sys.VersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service("versionService")
public class VersionServiceImpl extends ServiceImpl<VersionDao, VersionEntity> implements VersionService {
@Autowired
VersionService versionService;
@Autowired
VersionInfoService infoService;
@Autowired
VersionInfoDao versionInfoDao;
@Override
public PageUtils queryPage(Map<String, Object> params) {
Page<VersionEntity> page = this.selectPage(
new Query<VersionEntity>(params).getPage(),
new EntityWrapper<VersionEntity>()
);
return new PageUtils(page);
}
/**
* @return com.yymtmon.utils.R
* @Description: 最新版本信息
*/
@Override
public List<Map<String, Object>> selectLastInfo() {
List<Map<String, Object>> list = baseMapper.selectLastInfo();
List<Map<String, Object>> dataList = null;
Map<String, Object> m = null;
if (list != null && list.size() > 0) {
m = list.get(0);
dataList = new ArrayList<>();
// 获取指定列的数据
List introductionList = BigDataUtil.getColumnValueToList(list, "introduction", 0);
m.put("introduction", introductionList);
dataList.add(m);
}
return dataList;
}
/**
* @param params
* @return com.yymtmon.utils.R
* @Description: 保存
*/
@Override
public R saveData(Map<String, Object> params) {
String version = ConvertUtil.objToStrConverNull(params.get("version"));
String introduction = ConvertUtil.objToStrConverNull(params.get("introduction"));
String picturePath = ConvertUtil.objToStrConverNull(params.get("picturePath"));
String downloadPath = ConvertUtil.objToStrConverNull(params.get("downloadPath"));
Integer downloadType = ConvertUtil.parseInt(params.get("downloadType"));
if (version == null) {
return R.error("参数version不能为空");
}
if (introduction == null) {
return R.error("参数introduction不能为空");
}
if (downloadPath == null) {
return R.error("参数downloadPath不能为空");
}
if (VersionConstant.getMapVERSION_DOWNLOAD_TYPE(downloadType) == null) {
return R.error("参数downloadType有误 0关闭 1开启");
}
// 版本号只能含数字和点, 新版本必须比旧版本更大, 版本号必须唯一, 不发布的版本最多只能有一个(版本更新要很严谨!)
if (version != null) { // 校验版本
// 1.版本号只能含数字和点, 第一位不能为小数点
String legalChar = "0123456789.";
if (version.length() < 3 || !version.contains(".")) {
return R.error("版本号长度必须大于等于3, 且要包含数字和点");
}
if (".".equals(version.substring(0, 1))) {
return R.error("第一位不能为小数点, 必须是数字");
}
for (int i = 0; i < version.length(); i++) {
if (i == version.length() - 1) {
if (!legalChar.contains(version.substring(i))) {
return R.error("版本号只能含数字和点");
}
} else {
if (!legalChar.contains(version.substring(i, i + 1))) {
return R.error("版本号只能含数字和点");
}
}
}
// 2.新版本必须比旧版本更大,版本号必须唯一
// 获取最新的版本号
List<Map<String, Object>> lastList = versionService.selectLastInfo();
if (lastList != null && lastList.size() > 0) {
String lastVersion = (String) lastList.get(0).get("version");
int compareResult = PublicUtils.compareVersion(version, lastVersion);
if (compareResult != 1) {
return R.error("新版本号必须比旧版本号更大");
}
}
VersionEntity entity = versionService.selectOne(
new EntityWrapper<VersionEntity>()
.eq("version", version));
if (entity != null) {
return R.error("当前版本号已存在, 版本号必须唯一");
}
// 3.不发布的版本最多只能有一个(严谨一点)
// 获取不发布的数量
int count = baseMapper.queryCountNotReleaseData();
if (count > 0) {
return R.error("请先将那些尚未发布的版本发布后,在执行新增版本的操作");
}
}
// 其他校验
if ("[]".equals(picturePath)) {
picturePath = null;
}
if (picturePath != null) {
if (!picturePath.contains("[") || !picturePath.contains("]")) {
return R.error("picturePath必须是数组格式");
}
}
if (!introduction.contains("[") || !introduction.contains("]")) {
return R.error("introduction版本更新内容必须是数组格式");
}
// 校验下载链接 (外部链接类型要校验, 附件上传类型不用校验)
if (VersionConstant.VERSION_DOWNLOAD_TYPE_EXT_URL == downloadType) {
if (!PublicUtils.isHttpUrl(downloadPath)) {
return R.error("下载链接不合法,请输入正确的下载链接");
}
}
// 添加一个新版本,默认是关闭发布的状态,如果填写的内容有误,可以进行修改删除
// 默认值
VersionEntity versionEntity = new VersionEntity();
versionEntity.setCreateTime(new Date());
versionEntity.setIsDelete(DeleteSymble.IS_NORMAL);
versionEntity.setIsRelease(VersionConstant.VERSION_RELEASE_CLOSE);
// 参数值
versionEntity.setDownloadPath(downloadPath);
versionEntity.setDownloadType(downloadType);
versionEntity.setPicturePath(picturePath);
versionEntity.setVersion(version);
// 避免id已存在的情况
try {
versionService.insert(versionEntity);
} catch (Exception e) {
System.out.println("id = " + versionEntity.getId() + "被占用了...");
// 获取当前最大的版本ID
List<Map<String, Object>> maxList = baseMapper.queryMaxVersionId();
Long maxId = (Long) maxList.get(0).get("id");
versionEntity.setId(maxId + 1);
versionService.insertAllColumn(versionEntity);
}
// 版本更新内容信息
introduction = introduction.substring(1, introduction.length() - 1);
String[] introArr = introduction.split(",");
Long versionId = versionEntity.getId();
for (int i = 0; i < introArr.length; i++) {
VersionInfoEntity infoEntity = new VersionInfoEntity();
infoEntity.setVersionId(versionId);
infoEntity.setIsDelete(DeleteSymble.IS_NORMAL);
infoEntity.setIntroduction(introArr[i]);
infoEntity.setOrderNum(i + 1);
infoService.insert(infoEntity);
}
return R.ok();
}
/**
* @param params
* @param topUrl
* @return com.yymtmon.utils.R
* @Description: 列表
*/
@Override
public R queryPageData(Map<String, Object> params, String topUrl) {
params = ConvertUtil.getParams(params);
params.put("isDel", DeleteSymble.IS_NORMAL);
List<Map<String, Object>> list = baseMapper.queryPageData(params);
// 处理下载链接 没前缀的添加前缀
if (list != null && list.size() >0) {
String downloadPath = "";
Integer downloadType = 0;
for (Map<String, Object> map : list) {
downloadPath = ConvertUtil.objToStrConverSpace(map.get("downloadPath"));
downloadType = ConvertUtil.parseInt(map.get("downloadType"));
if (downloadType == VersionConstant.VERSION_DOWNLOAD_TYPE_UPLOAD) {
downloadPath = topUrl + downloadPath;
map.put("downloadPath", downloadPath);
}
}
}
// 获取总记录数
int count = versionService.queryCountData(params);
PageUtils page = ConvertUtil.getPageUtil(params, list, count);
return R.ok().put("data", page);
}
/**
* @param params
* @return int
* @Description: 获取总记录数
*/
@Override
public int queryCountData(Map<String, Object> params) {
return baseMapper.queryCountData(params);
}
/**
* @param id
* @param topUrl
* @return com.yymtmon.utils.R
* @Description: 信息
*/
@Override
public R selectInfo(Long id, String topUrl) {
VersionEntity versionEntity = versionService.selectById(id);
// 获取当前版本的所有版本更新内容
List<Map<String, Object>> list = versionInfoDao.queryDataByVersionId(id);
// 获取指定列的数据
List introductionList = BigDataUtil.getColumnValueToList(list, "introduction", 0);
// 数据信息 po转map
Map<String, Object> map = EntityMapUtils.entityToMap(versionEntity);
// 处理下载链接 没前缀的添加前缀
String downloadPath = "";
Integer downloadType = 0;
downloadPath = ConvertUtil.objToStrConverSpace(map.get("downloadPath"));
downloadType = ConvertUtil.parseInt(map.get("downloadType"));
if (downloadType == VersionConstant.VERSION_DOWNLOAD_TYPE_UPLOAD) {
downloadPath = topUrl + downloadPath;
map.put("downloadPath", downloadPath);
}
// 字符串转数组
String picturePath = ConvertUtil.objToStrConverNull(map.get("picturePath"));
if (picturePath != null && picturePath.length() > 2) {
picturePath = picturePath.substring(1, picturePath.length() - 1);
String[] picArr = picturePath.split(",");
map.put("picturePath", picArr);
}
map.put("introduction", introductionList);
return R.ok().put("data", map);
}
/**
* @param idList
* @return com.yymtmon.utils.R
* @Description: 删除/批量删除
*/
@Override
public R deleteData(List idList) {
Map map = new HashMap();
map.put("idList", idList);
map.put("isDel", DeleteSymble.IS_DELETE);
map.put("updateTime", new Date());
baseMapper.deleteData(map);
return R.ok();
}
/**
* @param params
* @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
* @Description: 当前版本信息
*/
@Override
public List<Map<String, Object>> selectCurrentInfoByVersion(Map<String, Object> params) {
List<Map<String, Object>> list = baseMapper.selectCurrentInfoByVersion(params);
List<Map<String, Object>> dataList = null;
Map<String, Object> m = null;
if (list != null && list.size() > 0) {
m = list.get(0);
dataList = new ArrayList<>();
// 获取指定列的数据
List introductionList = BigDataUtil.getColumnValueToList(list, "introduction", 0);
m.put("introduction", introductionList);
dataList.add(m);
}
return dataList;
}
}
VersionDao.java
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.yymt.entity.sys.VersionEntity;
import java.util.List;
import java.util.Map;
/**
* 版本信息
*/
public interface VersionDao extends BaseMapper<VersionEntity> {
/**
* @Description: 最新版本信息
*/
List<Map<String, Object>> selectLastInfo();
/**
* @Description: 列表
*/
List<Map<String, Object>> queryPageData(Map<String, Object> params);
/**
* @Description: 获取总记录数
*/
int queryCountData(Map<String, Object> params);
/**
* @Description: 删除/批量删除
*/
void deleteData(Map map);
/**
* @Description: 获取不发布的数量
*/
int queryCountNotReleaseData();
/**
* @Description: 当前版本信息
*/
List<Map<String, Object>> selectCurrentInfoByVersion(Map<String, Object> params);
/**
* @Description: 获取当前最大的版本ID
*/
List<Map<String, Object>> queryMaxVersionId();
}
VersionDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis//DTD Mapper 3.0//EN" "http://mybatis/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yymt.dao.sys.VersionDao">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.yymt.entity.sys.VersionEntity" id="versionMap">
<result property="id" column="id"/>
<result property="version" column="version"/>
<result property="picturePath" column="picture_path"/>
<result property="downloadPath" column="download_path"/>
<result property="downloadType" column="download_type"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="releaseTime" column="release_time"/>
<result property="isRelease" column="is_release"/>
<result property="isDelete" column="is_delete"/>
</resultMap>
<sql id="Base_Column_List" >
id AS id,
version AS version,
picture_path AS picturePath,
download_path AS downloadPath,
download_type AS downloadType,
create_time AS createTime,
update_time AS updateTime,
release_time AS releaseTime,
is_release AS isRelease,
is_delete AS isDelete,
</sql>
<select id="queryPageData" resultType="map">
SELECT
a.id AS id,
a.version AS version,
a.picture_path AS picturePath,
a.download_path AS downloadPath,
a.download_type AS downloadType,
a.create_time AS createTime,
a.update_time AS updateTime,
a.release_time AS releaseTime,
a.is_release AS isRelease,
a.is_delete AS isDelete
FROM tb_version a
WHERE 1= 1
AND a.is_delete = #{isDel}
<!-- 关键字 -->
<if test="titleKeyword != null and titleKeyword != ''">
AND (a.version LIKE CONCAT('%',#{titleKeyword},'%'))
</if>
ORDER BY a.create_time DESC
LIMIT #{index},#{pageSize}
</select>
<select id="queryCountData" resultType="int">
SELECT count(1) FROM tb_version a
WHERE 1= 1
AND a.is_delete = #{isDel}
<!-- 关键字 -->
<if test="titleKeyword != null and titleKeyword != ''">
AND (a.version LIKE CONCAT('%',#{titleKeyword},'%'))
</if>
</select>
<select id="selectLastInfo" resultType="map">
SELECT
b.*,
c.introduction
FROM
(
SELECT
*
FROM
tb_version a
WHERE
a.is_delete = 0
AND a.is_release = 1
AND a.release_time IS NOT NULL
AND a.download_path IS NOT NULL
AND a.download_type IS NOT NULL
AND a.version IS NOT NULL
ORDER BY
a.release_time DESC
LIMIT 1
) b
LEFT JOIN tb_version_info c ON b.id = c.version_id
<!-- WHERE
c.is_delete = 0 -->
ORDER BY
c.order_num
</select>
<update id="deleteData">
UPDATE tb_version a
SET a.is_delete = #{isDel},
a.update_time = #{updateTime}
<where>
id
<foreach collection="idList" item="id" open="in (" close=")" separator=",">
#{id}
</foreach>
</where>
</update>
<select id="queryCountNotReleaseData" resultType="int">
SELECT count(1) FROM tb_version a
WHERE 1= 1
AND a.is_delete = 0
AND a.is_release = 0
</select>
<select id="selectCurrentInfoByVersion" resultType="map">
SELECT
b.*,
c.introduction
FROM
(
SELECT
*
FROM
tb_version a
WHERE
a.is_delete = 0
AND a.is_release = 1
AND a.release_time IS NOT NULL
AND a.download_path IS NOT NULL
AND a.download_type IS NOT NULL
AND a.version = #{version}
ORDER BY
a.release_time DESC
LIMIT 1
) b
LEFT JOIN tb_version_info c ON b.id = c.version_id
<!-- WHERE
c.is_delete = 0 -->
ORDER BY
c.order_num
</select>
<select id="queryMaxVersionId" resultType="map">
SELECT id FROM tb_version
ORDER BY id DESC LIMIT 1
</select>
</mapper>
app端
VersionController.java
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.yymt.common.annotation.Login;
import com.yymt.common.utils.ConvertUtil;
import com.yymt.common.utils.R;
import com.yymt.dao.sys.VersionDao;
import com.yymt.entity.sys.VersionEntity;
import com.yymt.modules.controller.base.BaseController;
import com.yymt.service.sys.VersionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* 版本信息
*/
@RestController
@RequestMapping("version")
@Api(tags = "版本信息")
public class VersionController{
@Autowired
private VersionService versionService;
@Autowired
private VersionDao versionDao;
@PostMapping("/currentInfo")
@ApiOperation(value = "当前版本信息")
@Login
public R currentInfo( @ApiParam("参数说明 version:版本号(必填)")
@RequestBody Map<String, Object> params) {
String version = ConvertUtil.objToStrConverNull(params.get("version"));
if (version == null) {
return R.error("version版本号不能为空");
}
VersionEntity versionEntity = versionService.selectOne(
new EntityWrapper<VersionEntity>()
.eq("version", version));
if (versionEntity == null) {
return R.error("版本" + version + "不存在");
}
return versionService.selectInfo(versionEntity.getId(), getTopUrl());
}
@PostMapping("/lastInfo")
@ApiOperation(value = "检查版本(最新版本信息)")
@Login
public R lastInfo(){
List<Map<String, Object>> list = versionDao.selectLastInfo();
if (list == null) {
return R.ok().put("data", "当前已是最新版本");
}
Long id = ConvertUtil.parseLong(list.get(0).get("id"));
VersionEntity version = versionService.selectById(id);
if (version == null) {
return R.error("该数据不存在");
}
return versionService.selectInfo(id, getTopUrl());
}
/**
* @Description: app下载/版本更新(后端提供下载接口, 安卓端调用api安装即可) 要用手机测试!
*/
@Login
@GetMapping("/download/{id}")
@ApiOperation(value = "app下载/版本更新(要用手机测试!)", produces="application/octet-stream")
public void downloadPicture(@PathVariable("id") Long id, HttpServletResponse response) throws Exception {
VersionEntity versionEntity = versionService.selectById(id);
if (versionEntity == null) {
return;
}
String downloadPath = versionEntity.getDownloadPath();
downloadApp(downloadPath, response);
}
public void downloadApp(String appPath, HttpServletResponse response) {
// 获取文件的扩展名
String suffix = appPath.substring(appPath.lastIndexOf("."));
if (appPath != "" && !appPath.equals(null)) {
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
URL url = new URL(appPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Type", "application/vnd.android.package-archive");
response.setHeader("Content-disposition", "attachment; filename=" + System.currentTimeMillis() + suffix);
in = new BufferedInputStream(inStream);
out = new BufferedOutputStream(response.getOutputStream());
byte[] data = new byte[1024];
int size = 0;
int len = 0;
while (-1 != (len = in.read(data, 0, data.length))) {
size += len;
out.write(data, 0, len);
}
response.addHeader("Content-Length", size + "");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.flush();
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
更多推荐
app下载 - app版本更新 (实测可行版)
发布评论