我正在创建一个关于我们的Java / JSP Web应用程序的初始,广泛的静态代码分析报告(当然是遗产;-),用于管理以提高对质量问题的认识。主要的Java代码没有问题,有很多免费工具可用,例如PMD,Checkstyle,Classcycle等。
但是JSP呢?我们的JSP中嵌入了相当多的Java代码(不幸的是),这需要进行分析。 我可以使用哪些工具或者我需要遵循哪些流程来静态分析JSP?
答案 0 :(得分:3)
一个非常简单的指标可能适用于您的目的 - “这个jsp是否包含scriptlet”或“行数scriptlet代码”,你应该能够用grep或类似的东西拼凑起来。
如果您正在向管理层宣传解决问题的时间,那么详细信息会增加任何价值吗?
----编辑----
快速谷歌建议您可以使用此提取我上面建议的jsps统计数据
http://www.semanticdesigns.com/Products/SearchEngine/
在这个问题中建议作为答案
What would be a good way to measure the size of a JSP project?
答案 1 :(得分:3)
正如亨利指出的那样,JSP的一个好指标是"行数小程序代码"。这可以通过一些正则表达式来完成。
我发现代码行与行HTML(=LoC_Java/LoC_Html
)的比率最具表现力:这个数字越小越好。比率高达20或30%看起来不错,但值超过50%甚至> 1 不好。在我的分析中,我发现JSP的比率最高为6(非常糟糕)。
页面指令的数量也提供了粗略的洞察力。由于这个数字主要是由进口引起的,因此高数字表示高耦合。
PMD中提供了JSP Ruleset的类似指标。是基于HTML页面分析,并能够报告scriptlet的数量,scriptlet的长度,重复的导入和编码问题以及纯HTML反模式。
答案 2 :(得分:1)
我不想听起来很痛苦,但是有什么想摆脱这个?
我认为(我可能错了)在JSP上获取代码质量指标并不是很有用,因为基础实际上是一种非常糟糕的做法。
就个人而言,我会尝试投入任何资源或时间来确定如何将逻辑从JSP迁移到MVC或DCI框架。
答案 3 :(得分:0)
老实说,这种分析(如果可能的话)不会给你什么。 JSP中的混合代码很糟糕。如果最初无法迁移到任何MVC框架,那么只有解决方案是至少在服务类中移动它们。之后,这些服务类可以更容易地重复使用和分析。
我最近工作的痛苦的jsp代码示例:该系统已有9年
oListCode.setDB(driverclass, databaseurl, databasetype.intValue());
java.util.Vector oVecActiveStatusListCodes = oListCode.getListCodes(13, user.getAdminId());
java.text.DecimalFormat dformat = new java.text.DecimalFormat("###0.00");
java.text.DecimalFormat averageformat = new java.text.DecimalFormat("###0.##");
java.util.Vector userDirectoryVector = new java.util.Vector();
String searchoptionvalue = request.getParameter("iscombinesearch");
if (searchoptionvalue != null && searchoptionvalue.equals("on")) {
java.util.Vector oVectorStudents = (java.util.Vector) session.getAttribute("studentsearchresult");
if (oVectorStudents != null) {
oVector.addAll(oVectorStudents);
}
}
java.util.Vector<StatusSequenceInfo> oStaSeqVector = student.getStatusSequence(user.getAdminId());
java.util.Vector<StatusSequenceInfo> oEnrollStatusvecto = student.getProgramStatus(user.getAdminId());
String parameterList = "?columns=" + java.net.URLEncoder.encode(columns, "UTF-8") +
"&activestatus=" + activestatus +
"&studenttype=" + studenttype +
"&faith=" + faith +
"&race=" + race +
"&levelid=" + levelid +
"&levelidlist=" + levelidlist +
"&curriculumid=" + curriculumid +
"&programmeid=" + programmeid +
"&programmelevelid=" + programmelevelid +
"&semesterid=" + semesterid +
"&sex=" + sex +
"&idnumber=" + java.net.URLEncoder.encode(idnumber, "UTF-8") +
"&batchnumber=" + java.net.URLEncoder.encode(batchnumber, "UTF-8") +
"&firstname=" + java.net.URLEncoder.encode(firstname, "UTF-8") +
"&middlename=" + java.net.URLEncoder.encode(middlename, "UTF-8") +
"&lastname=" + java.net.URLEncoder.encode(lastname, "UTF-8") +
"&nationality=" + java.net.URLEncoder.encode(nationality, "UTF-8") +
"&address=" + java.net.URLEncoder.encode(address, "UTF-8") +
"&city=" + java.net.URLEncoder.encode(city, "UTF-8") +
"&state=" + java.net.URLEncoder.encode(state, "UTF-8") +
"&zip=" + java.net.URLEncoder.encode(zip, "UTF-8") +
"&homephone=" + homephone +
"&email=" + email +
"&advisor=" + java.net.URLEncoder.encode(advisor, "UTF-8") +
"&dob=" + dob +
"&visaexpiredate=" + java.net.URLEncoder.encode(visaexpiredate, "UTF-8") +
"®status=" + regStatus +
"®startDate=" + java.net.URLEncoder.encode(regstartDate, "UTF-8") +
"®endDate=" + java.net.URLEncoder.encode(regendDate, "UTF-8") +
"&shashmap=" + shashmap +
"&studentcount=" + studentcount + extendedurl;
String paginationLink = "admin_search_student_result.jsp" + parameterList;
long totalpage = new Double(Math.ceil(new Double(studentcount).doubleValue()/number_of_student)).longValue();//for pagination
String downloadStudentLink = "download_search_student_result.jsp" + parameterList + "&number_of_student=" + studentcount;
String printStudentLink = "admin_print_search_student_result.jsp" + parameterList + "&from_row=" + from_row;
%>
<html <%if (user.getLanguageId()>0 && oDictionary.getLanguageInfo(user.getLanguageId()).getDirection()==1) out.print("dir='rtl'");%>>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-15"/>
<title><%if (user.getRole()==6) out.print(oDictionary.getTranslatedWord(userLanguageId, "Sub-Administrator", adminId)); else out.print(oDictionary.getTranslatedWord(userLanguageId, "Administrator", adminId));%></title>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta name="Microsoft Theme" content="blocks 000, default">
<meta name="Microsoft Border" content="tlb, default">
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#CC0000" vlink="#CC0000" alink="#CC0000" leftmargin=5 topmargin=5 marginheight="0" marginwidth="0" onResize="if (navigator.family == 'nn4') window.location.reload()">
<p>
<table width=100%>
<td>
<img src="images/search.gif"> <b><font color="#666666" face="Arial, Arial, Helvetica" size="5"><%=oDictionary.getTranslatedWord(userLanguageId, "Search Result", adminId)%> </font></b>
</td>
<td align=right>
<table>
<%if (user.getRole()==4 || (user.getRole()==6 && (user.getOptions().indexOf("[STUDENT_RECORDS=") != -1 ))) {%>
<td>
<img src="images/write.gif"> <font face=arial size=2 color="#666666"><b><a href="new_student.jsp"><%=oDictionary.getTranslatedWord(userLanguageId, "New Student", adminId)%></a></font></b>
</td>
<%} %>
<td>
<img src="images/search.gif"> <font face=arial size=2 color="#666666"><b><a href="admin_search_student.jsp"><%=oDictionary.getTranslatedWord(userLanguageId, "Search Student", adminId)%></a></font></b>
</td>
<td>
<img src="images/read.gif"> <font face=arial size=2 color="#666666"><b><a href="students.jsp"><%=oDictionary.getTranslatedWord(userLanguageId, "Student Directory", adminId)%></a></font></b>
</td>
</table>
</td>
</table>
<%if (user.getRole()==4 || (user.getRole()==6 && (user.getOptions().indexOf("[STUDENT_RECORDS=F]") != -1 || user.getOptions().indexOf("[STUDENT_RECORDS=V]") != -1))) {%>
<table width="100%">
<tr>
<td>
<%@ include file="paginate.jsp" %>
</td>
<td align="right">
<table>
<tr>
<td>
<img src="images/download.jpg">
<a href="<%=downloadStudentLink%>" target=_><font face=arial size=-1>[<%=oDictionary.getTranslatedWord(userLanguageId, "Download search result", adminId)%>]</font></a>
</td>
<td>
<a href="<%=printStudentLink%>" target=_><img border=0 src="images/printer.gif"><font face=arial size=-1>[<%=oDictionary.getTranslatedWord(userLanguageId, "Print search result", adminId)%>]</font></a>
</td>
</tr>
</table>
</tr>
</table>
</font>
<table border="0" cellpadding="1" cellspacing="0" style="border-collapse: collapse" width="100%" id="AutoNumber1" bordercolordark="#666666" bordercolorlight="#999999">
<%if (!columns.equals("")) {%>
<tr>
<td nowrap bgcolor="<%=user.getColor()%>" bordercolor="#CC3300"><font face="Arial, Arial, Helvetica" size=2><b><%=oDictionary.getTranslatedWord(userLanguageId, "Student Name", adminId)%></b></font></td>
<%for (int i=0; i<oVectorColumns.size(); i++) {%>
<td nowrap bgcolor="<%=user.getColor()%>" bordercolor="#CC3300"><font face="Arial, Arial, Helvetica" size=2><b><%=oVectorColumns.get(i)%></b></font></td>
<%}%>
</tr>
<%
for (StudentInfo studentinfo:oVector) {
userDirectoryVector.add(new Long(studentinfo.getStudentId()));
java.util.HashMap oHashMapProfielValues = oExtendedProfile.getProfileFieldValues(studentinfo.getStudentId(), 1, user.getAdminId());
java.util.Vector oVectorStudentAllPrograms = registration.getStudentAllProgrammes(studentinfo.getStudentId(), user.getAdminId());
String programname = "";
String levelname = "";
String programlevelname = "";
String RegistrationDate="";
那么,清理这些相当分析是不是更好?答案是肯定的我认为