2017-07-17 172 views
2

我正在使用HP-ALM 12.01,它似乎充满了问题。我目前无法更新到其他版本。HP ALM Rest API QCSession 411身份验证

我想要访问其余api从JUnit自动上传测试结果。我正在使用显示here(示例应用程序 - > Infrastructure)的基础结构。从中,我的连接脚本将base64编码的登录信息传递给authentication-point/authenticate,并且我正在检索有效的LWSSO cookie。但是,当我使用此cookie连接到rest/site-session以接收我的QCSession cookie时,我收到了411长度要求错误。我试图将Content-Length硬编码到标头中,如下所示

public void GetQCSession(){ 
    String qcsessionurl = con.buildUrl("rest/site-session"); 
    Map<String, String> requestHeaders = new HashMap<String, String>(); 
    requestHeaders.put("Content-Type", "application/xml"); 
    requestHeaders.put("Accept", "application/xml"); 
    requestHeaders.put("Content-Length", "0"); 
    try { 
     Response resp = con.httpPost(qcsessionurl, null, requestHeaders); 
     con.updateCookies(resp); 
     System.out.println(resp.getStatusCode()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

这没有奏效。我也尝试修改基础结构以自动注入内容长度标题,如下所示

private void prepareHttpRequest(
     HttpURLConnection con, 
     Map<String, String> headers, 
     byte[] bytes, 
     String cookieString) throws IOException { 

    String contentType = null; 

    //attach cookie information if such exists 
    if ((cookieString != null) && !cookieString.isEmpty()) { 

     con.setRequestProperty("Cookie", cookieString); 
    } 

    //send data from headers 
    if (headers != null) { 

     //Skip the content-type header - should only be sent 
     //if you actually have any content to send. see below. 
     contentType = headers.remove("Content-Type"); 

     Iterator<Entry<String, String>> 
       headersIterator = headers.entrySet().iterator(); 
     while (headersIterator.hasNext()) { 
      Entry<String, String> header = headersIterator.next(); 
      con.setRequestProperty(header.getKey(), header.getValue()); 
     } 
    } 

    // If there's data to attach to the request, it's handled here. 
    // Note that if data exists, we take into account previously removed 
    // content-type. 
    if ((bytes != null) && (bytes.length > 0)) { 

     con.setDoOutput(true); 

     //warning: if you add content-type header then you MUST send 
     // information or receive error. 
     //so only do so if you're writing information... 
     if (contentType != null) { 
      con.setRequestProperty("Content-Type", contentType); 
     } 

     OutputStream out = con.getOutputStream(); 
     out.write(bytes); 
     out.flush(); 
     out.close(); 
     con.setRequestProperty("Content-Length", Integer.toString(bytes.length)); 
    } else { 
     con.setRequestProperty("Content-Length", "0"); 
    } 
} 

这也不起作用。 请注意,setRequestProperty只是一个.set(键,值)到MessageHeader

有没有人处理过这个问题或知道如何解决它?

请注意,邮递员不会发生这些问题。所有4个Cookie都是在网站会话后生成的。

回答

1

问题是Java的HttpURLConnection手动设置时会忽略某些属性。其中之一是内容长度。这是因为它会自动设置它自己。但是,如果你没有发送任何数据,它只是不发送它,由于它过时的http协议,ALM不接受,因为它预计会收到一个内容长度为0.

要解决这个问题,你必须告诉java允许重写的标题。这是通过运行

System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); 

更多信息完成,看这里Why does Content-Length HTTP header field use a value other than the one given in Java code?

+0

@Cyrusu你不必发送内容长度以获得QCsession cookie – Barney

0

pom.xml的依赖

<dependency> 
    <groupId>org.glassfish.jersey.bundles</groupId> 
    <artifactId>jaxrs-ri</artifactId> 
    <version>2.0</version> 
</dependency> 

Java代码:登录,获取第一个缺陷,注销

import java.util.Base64; 
import javax.ws.rs.client.Client; 
import javax.ws.rs.client.ClientBuilder; 
import javax.ws.rs.client.Entity; 
import javax.ws.rs.client.Invocation; 
import javax.ws.rs.client.WebTarget; 
import javax.ws.rs.core.Cookie; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 

public class App { 

    private static final String almURL = "https://abc.hp.com/qcbin"; 
    private static final String isAuthenticatedPath = "authentication-point/authenticate"; 
    private static final String qcSiteSession = "rest/site-session"; 
    private static final String logoutPath = "authentication-point/logout"; 
    private static String lswoocookie; 
    private static String qcsessioncookie; 

    public static String strDomain = "domain"; 
    public static String strProject = "project"; 
    public static String strUserName = "username"; 
    public static String strPassword = "password"; 

    public static Client client; 
    public static WebTarget target; 
    public static Invocation.Builder invocationBuilder; 
    public static Response res; 


    private static String getEncodedAuthString() { 
     String auth = strUserName + ":" + strPassword; 
     byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes()); 
     String authHeader = "Basic " + new String(encodedAuth); 

     return authHeader; 
    } 

    public static void main(String args[]){ 
     client = ClientBuilder.newBuilder().build(); 

     /* Get LWSSO Cookie */ 
     target = client.target(almURL).path(
       isAuthenticatedPath); 
     invocationBuilder = target.request(new String[] { "application/xml" }); 
     invocationBuilder.header("Authorization", getEncodedAuthString()); 
     res = invocationBuilder.get(); 
     lswoocookie = res.getCookies().get("LWSSO_COOKIE_KEY").getValue(); 

     /* Get QCSession Cookie */ 
     target = client.target(almURL).path(qcSiteSession); 
     invocationBuilder = target 
       .request(); 
     invocationBuilder.cookie("LWSSO_COOKIE_KEY", lswoocookie); 
     res = invocationBuilder.post(null); 
     qcsessioncookie = res.getCookies().get("QCSession").getValue(); 

     /* Get the first defect */ 
     String midPoint = "rest/domains/" + strDomain + "/projects/" + strProject; 
     target = client.target(almURL).path(midPoint).path("defects/1"); 
     invocationBuilder = target 
       .request(new String[] { "application/json" }); 
     invocationBuilder.cookie("LWSSO_COOKIE_KEY", lswoocookie); 
     invocationBuilder.cookie("QCSession", qcsessioncookie); 
     res = invocationBuilder.get(); 

     /* Logout */ 
     target = client.target(almURL).path(logoutPath); 
     invocationBuilder = target 
       .request(); 
     invocationBuilder.cookie("LWSSO_COOKIE_KEY", lswoocookie); 
     invocationBuilder.cookie("QCSession", qcsessioncookie); 
     res = invocationBuilder.post(null); 
    } 
}