2013-09-27 2 views
2

Я попытался сохранить файл .pdf, используя различные методы, которые я нашел в stackoverflow, включая FileUtils IO, однако я всегда получал бы его повреждение. Как я открыл поврежденный файл с помощью блокнота, я получил следующий материал:Как сохранить .pdf из браузера?

<HEAD> 

    <TITLE> 
     09010b129fasdf558a- 
    </TITLE> 

</HEAD> 


<HTML> 

<SCRIPT language="javascript" src="./js/windowClose.js"></SCRIPT> 

<LINK href="./theme/default.css" rel="stylesheet" type="text/css"> 
<LINK href="./theme/additions.css" rel="stylesheet" type="text/css"> 

<BODY leftmargin="0" topmargin="0"> 

<TABLE cellpadding="0" cellspacing="0" width="100%"> 
    <TR> 
     <TD class="mainSectionHeader"> 
      <A href="javascript:windowClose()" class="allLinks"> 
       CLOSE 
      </A> 
     </TD> 

    </TR> 

</TABLE> 

       <script language='javaScript'> 
        alert('Session timed out. Please login again.\n'); 
        window.close(); 
       </script> 



</BODY> 

</HTML> 

Позже я пытался сохранить .pdf файл из браузера, используя предоставленный ответ @BalusC. Это решение очень полезно: я смог избавиться от проблем session. Однако он также создает поврежденный .pdf. Но поскольку я открываю его с помощью блокнота, он совершенно другой. Там нет никаких проблем входа в систему больше, хотя:

<HTML> 

    <HEAD> 

     <TITLE> 
      Evidence System 
     </TITLE> 

    </HEAD> 

<LINK href="./theme/default.css" rel="stylesheet" type="text/css"> 

<TABLE cellpadding="0" cellspacing="0" class="tableWidth760" align="center"> 
    <TR> 
     <TD class="headerTextCtr"> 
      Evidence System 
     </TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 
      <HR size="1" noshade> 
     </TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 



<HTML> 
<HEAD> 
<link href="./theme/default.css" rel="stylesheet" type="text/css"> 
<script language="JavaScript"> 

function trim(str) 
{ 
    var trmd_str 

    if(str != "") 
    { 
     trmd_str = str.replace(/\s*/, "") 
     if (trmd_str != ""){ 

      trmd_str = trmd_str.replace(/\s*$/, "") 
     } 

    }else{ 
     trmd_str = str 
    } 
    return trmd_str 
} 

function validate(frm){ 
    //check for User name 
    var msg=""; 
    if(trim(frm.userName.value)==""){ 
     msg += "Please enter your user id.\n"; 
     frm.userName.focus(); 
    } 

    if(trim(frm.password.value)==""){ 
     msg += "Please enter your password.\n"; 
     frm.userName.focus(); 
    } 

    if (trim(msg)==""){ 
     frm.submit(); 
    }else{ 
     alert(msg); 
    } 
} 

function numCheck(event,frm){ 
    if(event.keyCode == 13){ 
      validate(frm); 
    } 
} 

</script> 
</HEAD> 

<BODY onLoad="document.frmLogin.userName.focus();"> 

<FORM name='frmLogin' method='post' action='./ServletVerify'> 
    <TABLE width="100%" cellspacing="20"> 
     <tr> 
      <td class="mainTextRt"> 
       Username 
       <input type="text" name="userName" maxlength="32" tabindex="1" value="" 
       onKeyPress="numCheck(event,this.form)" class="formTextField120"> 
      </TD> 
      <td class="mainTextLt"> 
       Password 
       <input type="password" name="password" maxlength="32" tabindex="2" value="" 
       onKeyPress="numCheck(event,this.form)" class="formTextField120"> 
      </TD> 
     </TR> 

     <tr>      
      <td colspan="2" class="mainTextCtr" style="color:red"> 
       Unknown Error 
      </td> 
     </tr> 

     <tr> 
      <td colspan="2" class="mainTextCtr"> 
       <input type="button" tabindex="3" value="Submit" onclick="validate(this.form)" > 
      </TD> 
     </TR> 
    </TABLE> 

    <INPUT TYPE="hidden" NAME="actionFlag" VALUE="inbox"> 
</FORM> 

</BODY> 
</HTML> 

     </TD> 
    </TR> 
    <TR> 
     <TD height="2"></TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 
      <HR size="1" noshade> 
     </TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 
      <LINK href="./theme/default.css" rel="stylesheet" type="text/css"> 

<TABLE width="80%" align="center" cellspacing="0" cellpadding="0"> 
    <TR> 
     <TD class="footerSubtext"> 
      Evidence Management System 
     </TD> 
    </TR> 

    <!-- For development builds, change the date accordingly when sending EAR files out to Wal-Mart --> 
    <TR> 
     <TD class="footerSubtext"> 
      Build:&nbsp;&nbsp;v3.1 
     </TD> 
    </TR> 

</TABLE> 
     </TD> 
    </TR> 
</TABLE> 

</HTML> 

Какие еще варианты у меня есть?

PS: Когда я пытаюсь сохранить файл вручную, используя CTRL+Shift+S, файл будет сохранен OK.

+0

отредактировал мой ответ Бурас .. Я думаю, что проблема может быть в этом месте. Он пытается сохранить файл html в отличие от pdf. См. Раздел ** EDIT **, в котором объясняется, что «это не двоичный файл», а читатель думает, что он «поврежден». – sircapsalot

ответ

3

Из errorneous ответа, который, как представляется, просто страница HTML ошибка:

оповещения ('Сессия таймаут Пожалуйста, войдите снова \ п.');

Таким образом, при загрузке файла PDF необходимо выполнить действительный сеанс HTTP. HTTP-сессия поддерживается файлом cookie. HTTP-сеанс, в свою очередь, содержит на стороне сервера обычно информацию о текущем активном и/или зарегистрированном пользователе.

Веб-драйвер Selenium полностью управляет печеньем полностью. Вы можете получить их программно следующим образом:

Set<Cookie> cookies = driver.manage().getCookies(); 

Когда вручную возиться с java.net.URL вне контроля селеном, вы должны убедиться сами, что соединение URL использует те же куки (и, таким образом, также поддерживая тот же сеанс HTTP) , Вы можете установить файлы cookie на URL-соединение следующим образом:

URLConnection connection = new URL(driver.getCurrentUrl()).openConnection(); 

for (Cookie cookie : driver.manage().getCookies()) { 
    String cookieHeader = cookie.getName() + "=" + cookie.getValue(); 
    connection.addRequestProperty("Cookie", cookieHeader); 
} 

InputStream input = connection.getInputStream(); // Write this to file. 
+0

Большое спасибо. У меня действительно были проблемы с мозгами. Теперь, когда я сохраняю .pdf, он по-прежнему поврежден, однако, по крайней мере, нет проблем с сеансом. Я опубликовал обновленную версию поврежденного файла, который я открыл с помощью блокнота. – Buras

+0

Возвращает ли файл 'driver.getCurrentUrl()' URL-адрес файла PDF или самой веб-страницы? Я уже нашел это подозрительным, но указание неправильного URL-адреса на первом месте является слишком очевидной ошибкой, которую я просто проигнорировал. – BalusC

+0

Да, да. Я дважды проверял его с помощью system.out.print – Buras

3

PDF-файл считается Binary File, и он поврежден из-за того, что работает copyUrlToFile(). Кстати, это выглядит как дубликат JAVA - Download Binary File (e.g. PDF) file from Webserver

Попробуйте этот обычай бинарный способ загрузки из -

public void downloadBinaryFile(String path) { 
    URL u = new URL(path); 
    URLConnection uc = u.openConnection(); 
    String contentType = uc.getContentType(); 
    int contentLength = uc.getContentLength(); 
    if (contentType.startsWith("text/") || contentLength == -1) { 
     throw new IOException("This is not a binary file."); 
    } 
    InputStream raw = uc.getInputStream(); 
    InputStream in = new BufferedInputStream(raw); 
    byte[] data = new byte[contentLength]; 
    int bytesRead = 0; 
    int offset = 0; 
    while (offset < contentLength) { 
     bytesRead = in.read(data, offset, data.length - offset); 
     if (bytesRead == -1) 
     break; 
     offset += bytesRead; 
    } 
    in.close(); 

    if (offset != contentLength) { 
     throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes"); 
    } 

    String filename = u.getFile().substring(filename.lastIndexOf('/') + 1); 
    FileOutputStream out = new FileOutputStream(filename); 
    out.write(data); 
    out.flush(); 
    out.close(); 
} 

EDIT: Это на самом деле звучит так, как будто вы не на странице, что вы думаете, .. вместо того, чтобы делать driver.getCurrentUrl()

У вашего сценария берет Url со ссылкой на PDF. Предположим, что есть ссылка вроде <a href='http://mysite.com/my.pdf' /> Вместо того, чтобы щелкнуть ее, а затем получить URL-адрес, просто возьмите href из этой ссылки и скачайте его.

String pdfPath = driver.findElement(By.id("someId")).getAttribute("href"); 
downloadBinaryFile(pdfPath); 
+0

Еще раз спасибо. Я получил исключение: это не двоичный файл – Buras

+0

Похоже, что 'contentLength == -1 ... => throw new IOException (" Это не двоичный файл. ");' – Buras

+0

Благодарим за обновление. Я дважды проверял использование 'system.out.print': ** драйвер находится по правильному URL **. Кроме того, прямое обращение к 'href' throws' java.net.MalformedURLException: неизвестный протокол: javascript', потому что 'href =" javascript: viewDocument ('0901asdasd09309d', '093094defkjhsdf', '23423432', 'General', ' -pleasae select ',' search ',' ') "' – Buras

2

Возможно, сервер может сжимать pdf. Вы можете использовать этот код, украденный из this answer обнаружить и распаковывать ответ от сервера,

InputStream is = driver.getCurrentUrl().openStream(); 
try { 
    InputStream decoded = decompressStream(is); 
    FileOutputStream output = new FileOutputStream(
     new File("C:\\Users\\myDocs\\myfolder\\myFile.pdf")); 
    try { 
     IOUtils.copy(decoded, output); 
    } 
    finally { 
     output.close(); 
    } 
} finally { 
    is.close(); 
} 

public static InputStream decompressStream(InputStream input) { 
    PushBackInputStream pb = new PushBackInputStream(input, 2); //we need a pushbackstream to look ahead 
    byte [] signature = new byte[2]; 
    pb.read(signature); //read the signature 
    pb.unread(signature); //push back the signature to the stream 
    if(signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b) //check if matches standard gzip maguc number 
     return new GZIPInputStream(pb); 
    else 
     return pb; 
} 
+0

Большое спасибо. Тем не менее, он сохраняет файл в месте назначения, так как я пытаюсь открыть файл, 'Adobe' говорит, что файл поврежден. – Buras

1

При попытке сохранить файл вручную с помощью CTRL + Shift + S, файл будет сохранен OK.

В то время как я выступаю с помощью Java для загрузки файла, есть не очень рекомендуется обходной путь, который прижимает Ctrl +Shift, + S: The программно Robot класс.

Это отстой для использования обходного пути, но он работает надежно, насколько я могу судить в браузерах и ОС, которые я пробовал. Этот код не должен попадать в какое-либо серьезное приложение. Но это нормально для тестов , если вы не сможете решить свою проблему правильным способом.

Robot robot = new Robot(); 

Нажмите Ctrl + Shift + S

robot.keyPress(KeyEvent.VK_CONTROL); 
robot.keyPress(KeyEvent.VK_SHIFT); 
robot.keyPress(KeyEvent.VK_S); 
robot.keyRelease(KeyEvent.VK_S); 
robot.keyRelease(KeyEvent.VK_SHIFT); 
robot.keyRelease(KeyEvent.VK_CONTROL); 

В браузерах и ОС, я знаю, вы должны быть в Save file диалога ввода имени файла. Вы можете ввести свой абсолютный путь:

robot.keyPress(KeyEvent.VK_C);  // C 
robot.keyRelease(KeyEvent.VK_C); 
robot.keyPress(KeyEvent.VK_COLON); // : (colon) 
robot.keyRelease(KeyEvent.VK_COLON); 
robot.keyPress(KeyEvent.VK_SLASH); ///(slash) 
robot.keyRelease(KeyEvent.VK_SLASH); 
// etc. for the whole file path 

robot.keyPress(KeyEvent.VK_ENTER); // confirm by pressing Enter in the end 
robot.keyRelease(KeyEvent.VK_ENTER); 

Чтобы получить коды клавиш, вы можете использовать KeyEvent#getExtendedKeyCodeForChar() (Java 7+ только), или How can I make Robot type a `:`? и Convert String to KeyEvents.

Смежные вопросы