Moodle上的HtmlUnit:尽管成功消息,但FileUpload仍然失败

时间:2015-05-15 12:29:38

标签: java file-upload moodle htmlunit

我尝试将文件上传到moodle2容器。这是通过yui完成的。为了跳过这些东西,我在我的WebClient(浏览器)中禁用了java脚本来获取“noscript”元素。在分析了这些之后,我进入了一个名为filepicker.php moodle的页面。

页面看起来像这样。

<form action="http://demo.moodle.net/repository/filepicker.php?ctx_id=41&amp;itemid=861552155&amp;env=editor&amp;course=2&amp;maxbytes=67108864&amp;areamaxbytes=-1&amp;maxfiles=-1&amp;subdirs=1&amp;sesskey=chtRoKYBlC&amp;action=browse&amp;draftpath=%2F&amp;savepath=%2F&amp;repo_id=3" method="post" enctype="multipart/form-data" style="display:inline">
    <label>Attachment: </label><input name="repo_upload_file" type="file"><br>
    <input name="action" value="upload" type="hidden"><br>
    <input name="draftpath" value="/" type="hidden"><br>
    <input name="savepath" value="/" type="hidden"><br>
    <input name="repo_id" value="3" type="hidden"><br>
    <input value="Upload this file" type="submit">
</form>

针对demo.moodle.org完成案例(在Mooodle课程中手动创建名为“Test”的文件夹'我的第一道菜'id = 2第一名):

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSpan;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


public class MoodleUpload {

    /** Instance of WebClient */
    private static final WebClient browser = new WebClient();

    /** Current HTMLPage */
    private HtmlPage currentPage;

    public MoodleUpload(){

        //intialize WebClient
        browser.getOptions().setJavaScriptEnabled(true);
        browser.getOptions().setRedirectEnabled(true);
        browser.getOptions().setThrowExceptionOnScriptError(false);
        browser.getOptions().setCssEnabled(false);
        browser.getOptions().setUseInsecureSSL(true);
        browser.getOptions().setThrowExceptionOnFailingStatusCode(false);
        browser.getCookieManager().setCookiesEnabled(true);

        try{
            login();            
            currentPage = (HtmlPage) browser.getPage("http://demo.moodle.net/course/view.php?id=2");
            modifyFolder(getFolderByName("Test"));

        } catch (Exception e){
             Logger.getLogger(MoodleUpload.class.getName()).log(Level.SEVERE, null, e);
        }

    }

    //perform login on moodle
    private void login() throws Exception{
        currentPage = (HtmlPage) browser.getPage("http://demo.moodle.net/");

        //get login-Form, fill in required fields and perform click
        ((HtmlTextInput) currentPage.getElementById("login_username")).setValueAttribute("manager");
        ((HtmlPasswordInput) currentPage.getElementById("login_password")).setText("sandbox");

        List<HtmlSubmitInput> inputs;
        inputs = (List) currentPage.getByXPath("//form/div/input[@type='submit']");
        inputs.get(0).click();
    }

    //finds link to folder with given name
    private String getFolderByName (String name) throws Exception{
        List<HtmlSpan> spans;
        spans = (List) currentPage.getByXPath("//a/span[@class='instancename' and text()='"+name+"']");


        System.out.println(((HtmlAnchor) spans.get(0).getEnclosingElement("a")).getHrefAttribute());

        return ((HtmlAnchor) spans.get(0).getEnclosingElement("a")).getHrefAttribute();
    }

    //trys to upload a file to a moodle folder
    private void modifyFolder(String path) throws Exception{

        //disable javascript to get noscript elements
        browser.getOptions().setJavaScriptEnabled(false);
        currentPage = (HtmlPage) browser.getPage(path);

        //click 'edit settings'
        List<HtmlAnchor> anchors;
        anchors = (List) currentPage.getByXPath("//ul/li/p[@class='tree_item leaf']/a[text()='Edit settings']");
        currentPage = (HtmlPage) browser.getPage(anchors.get(0).getHrefAttribute());

        //get file uploader
        List<HtmlElement> up;
        up = (List) currentPage.getByXPath("//noscript/div/object");        
        currentPage = (HtmlPage) browser.getPage(up.get(0).getAttribute("data"));

        //get "add file"-Page
        List<HtmlElement> elements;
        elements = (List) currentPage.getByXPath("//div[@class='filemanager-toolbar']");
        currentPage = (HtmlPage) browser.getPage(((HtmlAnchor) elements.get(0).getFirstChild()).getHrefAttribute());
        elements = (List) currentPage.getByXPath("//a[text()='Upload a file']");
        currentPage = (HtmlPage) browser.getPage(((HtmlAnchor) elements.get(0)).getHrefAttribute());

        //get file upload form
        elements = (List) currentPage.getByXPath("//form");
        HtmlForm uploadForm = (HtmlForm) elements.get(0);

        HtmlFileInput fileInput = uploadForm.getInputByName("repo_upload_file");

        fileInput.setValueAttribute("file:///F:/Test.xlsx");
        fileInput.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

        //submit
        List<HtmlSubmitInput> inputs;
        inputs = (List) currentPage.getByXPath("//form/input[@type='submit']");
        currentPage = inputs.get(0).click();

        System.out.println(currentPage.asText());


    }


    public static void main(String[] args){
        MoodleUpload tl = new MoodleUpload();
    }
}

如果我查看当前页面,我会从moodle获得成功消息。但该文件不在destlated容器中。我尝试了几次修改我的代码和对应于filepicker.php的'文档'的表单的action参数无济于事。如果我在Firefox中填写表单,一切正常。如果我跳过setValue-Call,我也会收到失败消息。所以似乎发生了一些事情。

也许这与其他隐藏字段有关?任何帮助表示赞赏。如果这是一个可行的解决方案,我也会使用javascript和yui功能。

2 个答案:

答案 0 :(得分:0)

奇怪的是,需要禁用JavaScript才能上传文件。

无论如何,真正的Chrome:

  1. 转到http://demo.moodle.net/course/modedit.php?update=1&return=1
  2. 点击“添加&#39;
  3. &#39;上传文件&#39;
  4. 上传实际文件
  5. &#39;文件已成功上传&#39;
  6. 刷新页面(http://demo.moodle.net/course/modedit.php?update=1&return=1
  7. &#34;没有可用的文件&#34;
  8. 那么,如何检查文件是否正确上传?还有其他方法可以上传启用了JavaScript的文件。

    作为旁注,单击()超链接总是更好,所以:

    currentPage = anchors.get(0).click();
    

    而不是

    currentPage = (HtmlPage) browser.getPage(anchors.get(0).getHrefAttribute());
    

答案 1 :(得分:0)

我在moodle安装中解决了这个问题。不幸的是,这并没有在demo.moodle.net上做到这一点。我做的很简单:我得到带有id&#34; id_submitbutton&#34;的HtmlSubmitInput。 (=保存)从编辑页面。按照我的显示上传文件后,我只需从此提交中调用click()。之后,该文件从moodle草案转移到经理。