【问题标题】:Access javascript data from Java (maven application)从 Java(maven 应用程序)访问 javascript 数据
【发布时间】:2023-03-20 09:35:01
【问题描述】:

我希望这是发布此内容的正确子论坛。 一般来说,我对 maven、vaadin 和 java 应用程序非常陌生,所以我希望你能帮助我,因为我不确定最好的方法是什么。 基本上我有一个maven项目(java 7),它使用javascript创建一个弹出窗口,里面有一个表单,允许你上传一个文件,在textarea中显示它的内容并发送它(文件的内容作为字符串)通过ajax请求到服务器。那是容易的部分。 我现在要做的是在 Java 中访问通过 ajax 发送的数据(包含上传文件数据的字符串),因为我需要通过一些验证来运行它。 我环顾四周,包括 vaadin 的书,以及一般的网络,考虑到我以前从未这样做过,似乎一种方法可能是有一个连接器,但它看起来有点太复杂了出现 - 从我从 vaadin https://vaadin.com/docs/-/part/framework/gwt/gwt-overview.html 的书中了解到 - 鉴于我拥有的结构,我将无法在我的项目中实现它 - 这与那里的结构不同。 所以,我对你们的问题是,鉴于我拥有的项目(只是一个普通的 Maven 项目),我从 Java 访问这些数据的最简单方法是什么? 这是项目中的一些代码,用于将内容放入上下文中:

import javax.servlet.annotation.WebServlet;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.JavaScript;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.client.ui.*;

@Theme("mytheme")
@Widgetset("my.vaadin.apptest.MyAppWidgetset")
@com.vaadin.annotations.JavaScript({"https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"

})
public class MyUI extends UI {
    @Override
    protected void init(VaadinRequest vaadinRequest) {
        final VerticalLayout layout = new VerticalLayout();
        layout.addStyleName("myLayout");//add class to main div        
        Label label = new Label("Hello Vaadin user. Use this application to upload files.");
        ...
        //HERE IS THE JAVASCRIPT CREATING AND INSTANTIATING THE POPUP AND THE AJAX CALL
        //CREATING POPUP
        JavaScript.getCurrent().execute(""
        +"var $HTMLpopup = $('<div class=\"popupContainer\">"
            +"<span class=\"cancelBtn big\"></span>"
            +"<div class=\"wrapper\">"
                +"<form action=\"\" id=\"fileForm\">"
                    +"<div class=\"mask\">"
                        +"<input type=\"file\" title=\" \"name=\"uploadFile\" class=\"uploadFile\" accept=\".mol,.sdf\">/*filters files to upload*/"
                        +"<span class=\"pseudoBtn\">Browse</span>"
                        +"<input type=\"text\" name=\"displayFile\" class=\"displayFile\" placeholder=\"no file loaded\">"
                        +"<span class=\"cancelBtn small\"></span>"
                    +"</div>"
                    +"<textarea class=\"fileResult\"></textarea>"
                    +"<button type=\"submit\" class=\"submitBtn\">Upload</button>"
                    +"<div class=\"clear\"></div>"
                +"</form>"
            +"</div>"
        +"</div>');"
        //INSTANTIATING THE POPUP
        +"$('.popupTriggerBtn').click(function(){"
            +"/*console.log('button clicked!');*/"
            +"var $body = $('body');"
            +"$HTMLpopup.appendTo($body);"
        +"});"
        //HERE IS THE AJAX BIT
        +"var $submitBtn = $HTMLpopup.find('.submitBtn');"
        +"$submitBtn.click(function(e){"
            +"e.preventDefault();/*prevent submission*/"                   
            +"if(isFileUploadEmpty()){/*IF EMPTY*/"
                +"/*alert('submit clicked');*/"
                +"removeError();"
                +"showError('empty');"                       
            + "}"
            +"else{/*IF NOT EMPTY*/"
                +"/*AJAX OPS*/"
                +"if (window.XMLHttpRequest){/*XMLHttpRequest SUPPORT?*/"
                    +"console.log('XMLHttpRequest supported!');"
                    +"var postData = returnFileAsString();/*returns the file as a string*/;"                           
                    +"/*console.log('here is the file as a string ' + postData);*/"
                    +"$.ajax({"
                        +"type:'post',"
                        +"url:'http://localhost:8080/apptest/',"
                        +"data:postData,"
                        +"contentType: 'application/x-www-form-urlencoded',"
                        +"success: function(responseData, textStatus, jqXHR){"
                            +"/*alert('data saved');*/"
                            +"console.log('responseData is ' + responseData);"
                            +"console.log('text status is ' + textStatus);"
                            +"console.log('the data submitted is ' + postData );"
                        +"},"
                        +"error: function(jqXHR, textStatus, errorThrown){"
                            +"console.log(errorThrown);"
                            +"alert('an error has occurred!');"
                        +"}"   
                    +"});"
                +"}"
            +"}"
        +"});"       
    +"");
    //ADDING COMPONENTS
    layout.addComponents( label, button );
    layout.setMargin(true);
    layout.setSpacing(true);

    setContent(layout);
}

链接到 pastebin 这里http://pastebin.com/mSEJq0HT 因此,postData 包含我传递给服务器并且我想在 Java 中访问的字符串。 我早些时候遇到过这个问题,这可能是也可能不是另一种处理方式vaadin with ajax。你们有什么感想? 任何帮助将不胜感激,谢谢

【问题讨论】:

  • 不要弄乱Vaddin客户端服务器通信。只需在 java 端的相应字段中添加valueChangeListener,您就会在值发生更改时收到通知。
  • 这是一个简化的例子吗?如果不是,那为什么还要在这一点上打扰 vaadin,当您所做的只是将一些巨大的 blob 连接的 JS 字符串发送到客户端以引导一些 jquery 将文件发送到另一个端点?否则,为什么不使用 vaadin Window、Upload、TextArea...?
  • 所有有效积分,但我使用 vaadin 的原因是因为我正在学习,此时我对 JS 比对 Java/vaddin 组件更有信心,因此发送所有的 JS 字符串。同意上传,textAreas 等会更好,但是当我重构它时,当我感觉更有信心之后,那就是。现在,我想我会理解使用 RPC 等的原理,这就是为什么我会这样做,即使它不是最好的方式......

标签: javascript java ajax maven vaadin


【解决方案1】:

好吧,首先我需要表达我的深切关注,即您以一种非常奇怪的方式使用了错误的工具来达到您想要的效果。我不会深入探讨该主题,但让我们指出 Vaadin 框架的主要目的是允许开发人员用 Java 编写组件(类似于 Swing 组件)以避免 JavaScript 混乱。是的,您可以使用 Vaadin 框架运行 JavaScript,但您应该尽可能避免使用它。

好的,现在让我们进入黑客攻击。您有两个选项可以让您的服务器捕获文件数据(如您所说,这是一个字符串):

a) 摆脱手动构建 XMLHttpRequest。让 Vaadin 为您处理。而不是

+"$.ajax({"
+"type:'post',"
+"url:'http://localhost:8080/apptest/',"
...

只是调用 JavaScript 函数,让我们说

sendFileContentToTheServer(postData)

接下来您需要在服务器端注册 JavaScript 回调(阅读:Vaadin)。在你的代码中的某个地方(在哪里并不重要,只要确保代码至少被调用一次 - 最好是一次)放置:

JavaScript.getCurrent().addFunction("sendFileContentToTheServer", new JavaScriptFunction() {
    public void call(JSONArray arguments) throws JSONException {
        System.out.println(arguments.getString(0));
        //do whatever you want with your data - its under arguments.getString(0)
    }
});

就是这样。 Vaadin 将为您管理 RPC 调用。您的页面不会重新加载,您将在服务器端获取数据。

b) 第二种方法更棘手。技术上可以手动构造 XMLHttpRequest 并使用 Vaadin 在服务器上接收数据。您需要做的是注册 JavaServlet(不是 VaadinServlet)。将数据发送到 JavaServlet。然后通过一些代理或引用调用现有的 VaadinUI。这是一种复杂的做事方式,你已经把它弄得很棘手,所以我不会深入探讨。

【讨论】:

  • 谢谢。至于您的担忧,是的,您是对的,但就像我之前所说的,计划是在不久的某个时候重构它,摆脱所有 js 并用 java 代码替换它。恐怕我必须用 ajax 来实现它。我还有一个关于第一个解决方案的问题。在 vaadin 书中,他们使用 javascript 连接器让 js 与 java 部分对话,然后他们注册 RPC,我想知道这是否是一种需要考虑的方法?
  • 你也可以这样做。但这只是一种更多的工作。它至少需要对 Vaadin 框架有很好的了解,而且您可能需要重新编译小部件集才能使其工作。我的答案中没有涉及到这一点,因为它只会给您的代码添加噪音。如果您有更复杂的 ui 组件和与 JavaScript 的强大集成,那么这将是您的选择。现在你不需要它。关于您对 Ajax 的需求 - 您是否知道 RPC 包装了 Ajax,所以最终您在技术上仍然会收到一个 ajax 请求。阅读stackoverflow.com/questions/13735602
  • 谢谢。事实上,使用 RPC 调用会很有趣。另外,我需要习惯它们,因为我将来会经常使用它们。我正在在线阅读各种教程以完成此操作,我将再次发布,可能在一个单独的线程中,因为我正在显着更新我的代码。至于vaadin框架的好知识,我需要学习,所以我还不如...
  • 很高兴听到。仅供参考,如果您发现我的回答对您的问题有效并且它帮助您解决了问题,您可能想要接受它/支持它。通过这种方式,您可以为社区做出贡献。
猜你喜欢
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 2012-11-20
  • 1970-01-01
  • 2012-03-07
相关资源
最近更新 更多