用于静态分析JSP的工具或过程是什么?

时间:2013-03-14 10:44:18

标签: java jsp static-analysis

我正在创建一个关于我们的Java / JSP Web应用程序的初始,广泛的静态代码分析报告(当然是遗产;-),用于管理以提高对质量问题的认识。主要的Java代码没有问题,有很多免费工具可用,例如PMD,Checkstyle,Classcycle等。

但是JSP呢?我们的JSP中嵌入了相当多的Java代码(不幸的是),这需要进行分析。 我可以使用哪些工具或者我需要遵循哪些流程来静态分析JSP?

  • 我知道PMD 5的新功能涉及JSP,值得探讨吗?
  • 我可以以某种方式生成JSP的源Servlet并使用基本的Java分析工具,如果是这样,那么获取JSP的Java源代码的最简单方法是什么?

4 个答案:

答案 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") +
                    "&regstatus=" + regStatus +
                    "&regstartDate=" + java.net.URLEncoder.encode(regstartDate, "UTF-8") +
                    "&regendDate=" + 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)%> &nbsp;&nbsp;</font></b>
</td>
<td align=right>
<table>
<%if (user.getRole()==4 || (user.getRole()==6 && (user.getOptions().indexOf("[STUDENT_RECORDS=") != -1 ))) {%>
<td>
&nbsp;<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>
&nbsp;<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>
&nbsp;<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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<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="";

那么,清理这些相当分析是不是更好?答案是肯定的我认为