APP管理平台--后端篇,整体架构(二)

介于Spring框架的能力,通过各种注释将接口Api定义。

Controller层

区分当前项目使用模块,分为File,App,User,Module四个。

1. FileController

用于文件上传使用,包括apk文件,ipa文件,图片等。项目中没有单独的FTP服务器,因此数据直接存放至当前部署路径下的(规范做法请放至FTP)。

@RestController
@RequestMapping("/file")
public class FileController {
    private static final String FILE_LOCATION_URL = "http://localhost/uploadFile/";
    @Autowired
    private HttpServletRequest request;

    @PostMapping("/upload")
    public BaseResp<?> uploadFile(@RequestParam(value = "file") MultipartFile file) {
        Log.info(file.getName() + "---" + file.getOriginalFilename() + "----" + file.getContentType() + "---" + file.getSize());
        StringBuilder fileName = new StringBuilder();
        fileName.append(UUID.randomUUID().toString().replaceAll("-", ""));
        if (file.getOriginalFilename() != null && !file.getOriginalFilename().isEmpty() && file.getOriginalFilename().lastIndexOf(".") != -1) {
            String name = file.getOriginalFilename();
            fileName.append(name.substring(name.lastIndexOf(".")));
        }
        try {
            //存入apache文件中,可根据request获取到当前目录,存放至tomcat目录里,我这里存放在了apache,htdocs目录里
            File uploadFile = new File("/apache/htdocs/uploadFile");
            if (!uploadFile.exists()) {
                Log.info("创建上传文件夹:" + uploadFile.mkdirs());
            }
            File saveFile = new File(uploadFile, fileName.toString());
            file.transferTo(saveFile);
            String apkInfo = parseApkWithWins(saveFile);
            Map<String, String> map = new HashMap<>();
            map.put("fileUrl", FILE_LOCATION_URL + fileName);
            if (fileName.toString().endsWith("apk") || fileName.toString().endsWith("APK")) {
                map.put("extraInfo", apkInfo);
            }
            return new BaseResp<>(ResultConstant.SUCCESS, "success", map);
        } catch (IOException e) {
            e.printStackTrace();
            return new BaseResp<>(ResultConstant.FAILED, "failed");
        }
    }

	/**
	* windows环境下解析apk内容,通过aapt进行解析,aapt放置在resources文件夹下
	*/
	private String parseApkWithWins(File file) {
		//获取aapt在部署服务器里的地址
        String path = getClass().getClassLoader().getResource("aapt.exe").getPath();
        //执行命令
        String cmd = path + " dump badging " + file.getPath();
        Runtime runtime = Runtime.getRuntime();
        Process process = null;
        try {
            process = runtime.exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
        String line = null;
        StringBuilder build = new StringBuilder();
        while (true) {
            try {
                if ((line = br.readLine()) == null) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            build.append(line).append("\n");
        }
        String[] strings = build.toString().split("\n");
        Map<String, String> map = new HashMap<>();
        for (String string : strings) {
        	//包名处理
            if (string.startsWith("package:")) {
                String[] packages = string.split(" ");
                //包名后可能存在多个name=xxxx,因此需要循环处理,只要了一个,我也不知道为啥
                for (String aPackage : packages) {
                    if (aPackage.startsWith("name=")) {
                        map.put(aPackage.substring(aPackage.indexOf("'") + 1, aPackage.length() - 1), "package");
                        break;
                    }
                }
            } else if (string.startsWith("uses-permission")) {
            	//权限列出
                Log.info("权限:" + string);
            } else if (string.startsWith("application-label")) {
            	//获取app名字
                String name = string.substring(string.indexOf("'") + 1, string.length() - 1);
                map.put(name, "name");
            }
        }
        Map<String, String> result = new HashMap<>();
        Set<String> keys = map.keySet();
        int index = 1;
        //对可能存在一个key多个值的进行处理
        for (String key : keys) {
            String value = map.get(key);
            if (result.containsKey(value)) {
                value = value + index++;
            }
            result.put(value, key);
        }
        return JSON.toJSONString(result);
    }
}

2. AppController

该内容主要用于接口app相关信息

@RestController
@RequestMapping("/app")
public class AppController {
    @Resource
    private AppService appService;

    @GetMapping("/list")
    public BaseResp<?> queryAppList() {
        return appService.queryAppList();
    }
    
	@PostMapping("/uploadAppInfo")
    public BaseResp<?> uploadAppInfo(@RequestBody AppInfo req) {
        Log.info("app upload info -> " + JSON.toJSONString(req));
        if (req.getName() == null || req.getName().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "名字为空");
        }
        if (req.getAppVersion() == null || req.getAppVersion().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "版本号为空");
        }
        if (req.getPackageName() == null || req.getPackageName().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "包名为空");
        }
        if (req.getBusiness() == null || req.getBusiness().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "业务归属为空");
        }
        if (req.getDownloadUrl() == null || req.getDownloadUrl().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "下载地址为空");
        }
        if (req.getLogoUrl() == null || req.getLogoUrl().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "logo为空");
        }
        if (req.getDescribe() == null || req.getDescribe().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "描述为空");
        }
        if (req.getUpdateNote() == null || req.getUpdateNote().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "更新提示为空");
        }
        if (req.getContact() == null || req.getContact().isEmpty()) {
            return new BaseResp<>(ResultConstant.FAILED, "联系人为空");
        }
        return appService.handleAppInfo(req);
    }

    @GetMapping("/detail/{id}")
    public BaseResp<?> uploadAppInfo(@PathVariable(value = "id") String appId) {
        Log.info("app/detail/" + appId);
        if(appId == null || appId.isEmpty()){
            return new BaseResp<>(ResultConstant.FAILED, "id不能为空");
        }
        return appService.queryAppInfo(appId);
    }

}

3. UserController

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService mService;

    @PostMapping("/login")
    public BaseResp<?> userLogin(@RequestBody UserInfoReq req) {
        Log.info("login req  " + JSON.toJSONString(req));
        return mService.login(req);
    }

    @PostMapping("/register")
    public BaseResp<?> userRegister(@RequestBody UserInfoReq req) {
        Log.info("register req  " + JSON.toJSONString(req));
        return mService.registerUser(req);
    }
}

4. ModuleController

用于查看自建的maven仓库

@RestController
@RequestMapping("/module")
public class ModuleController {
    @Resource
    private ModuleService moduleService;
    @Autowired
    private HttpServletRequest request;

    @GetMapping("/list")
    public BaseResp<?> queryModuleList(@Valid QueryModuleReq req) {
        Log.info(JSON.toJSONString(req));
        return moduleService.queryModuleList();
    }

    @PostMapping("/{id}/update")
    public BaseResp<?> updateModuleInfo(@RequestBody UpdateModuleInfoReq req) {
        moduleService.updateInfo(req);
        return new BaseResp<>(ResultConstant.SUCCESS, "success");
    }

	/**
	* 更新远程maven组件库
	*/
    @GetMapping("/updateAllModulesFromRemote")
    public BaseResp<?> updateAllModulesFromRemote(){
        return  moduleService.updateAllModulesFromRemote();
    }

}

Services层

AppService

@Service
public class AppService {

    @Autowired
    SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    BaseDao dao;

    public BaseResp<?> queryAppList() {
        AppInfo appInfo = dao.newNullPropertiesObject(AppInfo.class);
        List<AppInfo> list = dao.queryByNotNullProperties(appInfo);
        QueryAppListResp resp = new QueryAppListResp();
        resp.setList(list);
        Log.info("response data -> " + JSON.toJSONString(resp));
        return new BaseResp<>(ResultConstant.SUCCESS, "", resp);
    }

    public BaseResp<?> handleAppInfo(AppInfo info) {
        AppInfo queryInfo = dao.newNullPropertiesObject(AppInfo.class);
        queryInfo.setPackageName(info.getPackageName());
        List<AppInfo> infos = dao.queryByNotNullProperties(queryInfo);
        if(infos != null && !infos.isEmpty()){
            return new BaseResp<>(ResultConstant.FAILED,"包名重复存在");
        }
        //往下数据库内没数据
        info.setUpdateTime(new Date());
        if (info.getId() == null) {
            info.setCreateTime(new Date());
            dao.save(info);
        } else {
            info.setCreateTime(null);
            dao.updateNotNullPropertiesById(info);
        }
        Log.info(JSON.toJSONString(info));
        return new BaseResp<>(ResultConstant.SUCCESS, "");
    }

    public BaseResp<?> queryAppInfo(String appId) {
        AppInfo appInfo = dao.queryById(AppInfo.class, Integer.parseInt(appId));
        Log.info("response ==> " + JSON.toJSONString(appInfo));
        return new BaseResp<>(ResultConstant.SUCCESS, "", appInfo);
    }
}

End

其他的类似就不细列了,最后整体就是这个样子
在这里插入图片描述
运行后直接部署到tomcat

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值