2015-09-29 127 views
2

我有一個基於servlet的應用程序(OAuth的實現),它代表了一些響應渲染JSP,如下面的例子:找不到JSTL標籤庫

private void doLoginPage(AuthorizationSession authzSession, String errorMsg, HttpServletRequest request, HttpServletResponse response) throws OAuthSystemException { 
    try { 
     response.setHeader(HTTP.CONTENT_TYPE, ContentType.create("text/html", "utf-8").toString()); 
     request.getRequestDispatcher("/WEB-INF/OAuthLogin.jsp").include(request, response); 
    } catch (Throwable e) { 
     throw new OAuthSystemException("Error generating login page", e); 
    } 
} 

下面是JSP文件(簡體):

<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %> 

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

<jsp:useBean id="errorMsg" scope="request" class="java.lang.String"/> 

<html> 
<head> 
<title>Sign In</title> 
</head> 
<body style="text-align: center;"> 
<h1>Sign In</h1> 
<div style="border: 1px black;"> 
    <c:if test="${!(empty errorMsg)}"> 
     <p style="color:red;">${errorMsg}</p> 
    </c:if> 
    <form method="post" action="<c:url value="/authorize"/>"> 
     <div><label for="email">Email:</label></div> 
     <div><input type="text" name="email" id="email"/></div> 
     <div><label for="password">Password:</label></div> 
     <div><input type="password" name="password" id="password"/></div> 
     <div><input type="submit" title="Sign In" /></div> 
    </form> 
</div> 
</body> 
</html> 

我有我的單元測試設置,這樣我可以作爲單元測試運行基於服務器的測試 ,注射了嘲笑,使用碼頭作爲一個進程內服務器 (好吧,所以它不是純粹的單元測試)。

由於我的單元測試的一部分,我寫了一個測試,以確保頁面被適當的時候呈現,並且它包括某些關鍵性能(我用TestNG和Hamcrest):

@Test 
public void testRequestGrantYieldsLoginPage() throws Exception { 
    HttpGet request = new HttpGet(String.format("%s/authorize?client_id=%s&redirect_uri=%s&response_type=token", 
      serverConnector.getServerURL(), 
      "*******secret*****", 
      URLEncoder.encode("*****secret*********", "UTF-8"))); 

    DefaultHttpClient httpClient = new SystemDefaultHttpClient(); 
    HttpResponse response = httpClient.execute(request); 

    assertThat(response, is(notNullValue())); 
    assertThat(response.getStatusLine().getStatusCode(), is(200)); 
    assertThat(response.getEntity().getContentType().toString(), containsString("text/html")); 

    String body = IOUtils.toString(response.getEntity().getContent()); 

    assertThat(body, allOf(
      is(notNullValue()), 
      containsString("value=\"gQwCAShitcuP-_2OY58lgw3YW0AfbLE8m62mrvXWvQbiDLJk9QnDTs7pc0HH\"") 
    )); 
} 

當我從我的IDE(的IntelliJ)運行我的單元測試,但是當我在Maven的神火運行它們,這個特殊的測試失敗,也能正常工作:服務器線程拋出一個異常,如下所示:

當然
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application 

這個原因測試的客戶端將失敗,因爲它返回e rror響應而不是預期的登錄頁面。

那麼這兩種測試環境有什麼不同,以及如何在兩種測試環境中進行測試?

回答

3

事實證明,默認情況下,Maven的Surefire插件採用了一種技巧,它創建一個僅供Manifest使用的JAR文件,以避免需要將完整的類路徑傳遞到分叉的JRE(請參閱this article)。 Jetty JSP處理器只是要求每個類加載器的URL列表,因此只能看到一個僅用於清單的JAR文件,而不是實際使用的所有JAR文件,因此找不到TLD文件。

簡單的解決方案,其也被記錄在該網頁上,是關掉useManifestOnlyJar選項,如下所示:

<plugins> 
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.18.1</version> 
    <configuration> 
     <useManifestOnlyJar>false</useManifestOnlyJar> 
    </configuration> 
    </plugin> 
    .... 
<plugin> 

這指示神火到滿類路徑直接傳遞到叉形JRE處理,從而允許它查找頂級域名。

+0

這對我來說在Maven測試中使用Spring-Boot嵌入式Tomcat和JSP來實現 – Schaka