目录
1,实验环境
2,前言(环境配置)
3,通过Java执行shell命令扫描项目
3.1 主要思路
3.2 参考代码
3.3 运行效果
4,通过sonarqube的webapi获取项目扫描结果
4.1 主要思路
4.2 参考代码
4.3 运行结果
1,实验环境
Windows10
sonarqube-6.7.4
sonar-scanner-2.8
2,前言(环境配置)
具体安装配置过程教程比较多,这里就不再详细介绍了。
1,在官网下载sonarqube和sonar-scanner后,解压、修改配置(主要是连接数据库);
至此,已经可以通过常规方法使用sonarqube扫描一个Java项目了,下面正片开始ε=ε=ε=(~ ̄▽ ̄)~
以下步骤均在sonarqube开启的前提下进行
3,通过Java执行shell命令扫描项目
3.1 主要思路
用户输入项目路径projectPath、项目名称/标识符projectName(这里默认将项目名称作为key);
在项目目录下创建sonarqube扫描所需的配置文件sonar-project.properties,并填入配置信息;
通过Runtime.getRuntime().exec执行命令行程序,并通过Process对象的waitFor函数了解进程的运行结果;
3.2 参考代码
import java.io.*;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Scanner;
import com.alibaba.fastjson.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Objects;
public class Main {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
// 输入配置信息
System.out.println("输入待扫描项目地址:");
String projectPath = input.nextLine();
String fileName = "sonar-project.properties";// 配置文件名称
System.out.println("输入项目名称:");
String projectName = input.nextLine();
String projectVersion = "1.0";
String sources = "src";
String binaries = "./";
// 创建配置文件
createFile(projectPath.concat("/"), fileName, projectName, projectVersion, sources, binaries);
// 运行命令行
runShell(projectPath);
}
/**
* 创建配置文件
* @param projectPath
* @param fileName
* @param projectName
* @param projectVersion
* @param sources
* @param binaries
*/
public static void createFile(String projectPath, String fileName,String projectName,
String projectVersion, String sources, String binaries) {
// 创建配置文件
File file = new File(projectPath, fileName);
if(file.exists()) {
System.out.println("配置文件已存在,开始更新配置");
} else {
try {
file.createNewFile();
System.out.println("配置文件创建成功,开始更新配置");
} catch (IOException e) {
e.printStackTrace();
}
}
// 向文件中添加配置信息
FileWriter fw;
try {
fw = new FileWriter(projectPath + fileName);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("sonar.projectKey=" + projectName + "\n");
bw.write("sonar.projectName=" + projectName + "\n");
bw.write("sonar.projectVersion=" + projectVersion + "\n");
bw.write("sonar.sources=" + sources + "\n");
bw.write("sonar.java.binaries=" + binaries + "\n");
bw.write("sonar.sourceEncoding=UTF-8\n");
bw.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println(2);
}
}
/**
* 打开命令行,切换到对应目录,执行sonar-scanner指令
* @param projectPath
*/
public static void runShell (String projectPath) {
try {
long startTime = System.currentTimeMillis();
Process proc = Runtime.getRuntime().exec("cmd.exe /c cd " + projectPath + "&& sonar-scanner");
int processCode = proc.waitFor();
if(processCode == 0) {
System.out.println("扫描完成");
long endTime = System.currentTimeMillis();
// 获取扫描时间
long usedTime = (endTime - startTime) / 1000;
System.out.println("扫描用时" + usedTime + "s");
System.out.println("-----------------------------");
} else {
System.out.println("扫描失败");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.3 运行效果
4,通过sonarqube的webapi获取项目扫描结果
4.1 主要思路
向接口(http://localhost:9000/api/measures/component?component=项目的key&metricKeys=想要获得的指标)发送HTTP请求,获得返回的json字符串;
4.2 参考代码
/**
* 根据项目名称获取sonarqube扫描结果(bugs、codeSmells、vulnerabilities)
* @param projectName
*/
public static void getJsonData(String projectName) {
String param1 = "component=" + projectName + "&metricKeys=bugs";
String param2 = "component=" + projectName + "&metricKeys=code_smells";
String param3 = "component=" + projectName + "&metricKeys=vulnerabilities";
System.out.println("bugs:" + getSonarMeasures(param1));
System.out.println("codeSmells:" + getSonarMeasures(param2));
System.out.println("vulnerabilities:" + getSonarMeasures(param3));
}
/**
* 根据参数获得相应的指标
* @param param 向接口发送的参数(bugs、codeSmells、vulnerabilities)
* @return 各种参数的值
*/
public static int getSonarMeasures(String param) {
PrintWriter out = null;
InputStream is = null;
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
int value = 0;
try {
String api = "http://localhost:9000/api/measures/component?";
URL url = new URL(api);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
// 发送参数
connection.setDoOutput(true);
out = new PrintWriter(connection.getOutputStream());
out.print(param);
out.flush();
// 接受结果
is = connection.getInputStream();
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
// 通过流读取结果
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
// 解析json数据
String backJson = sb.toString(); // 获得json字符串
JSONObject jsonObject = JSONObject.parseObject(backJson); // 将字符串转换为JSONObject对象
JSONObject componentObj = jsonObject.getJSONObject("component"); // 获取component的JSONObject对象
JSONArray measuresAry = componentObj.getJSONArray("measures"); // 由于是数组形式,先获取measures的JSONArray对象
JSONObject measuresObj = measuresAry.getJSONObject(0); // 获取measures的JSONObject对象
value = measuresObj.getIntValue("value");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(is != null) is.close();
if(br != null) br.close();
if(out != null) out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return value;
}
4.3 运行结果