0

I hope this is the right subforum to post this. I'm very new to maven, vaadin and java applications in general, so I hoped you could help me with this as I'm not sure what's the best way to go about it. Basically I have a maven project (java 7) which, using javascript, creates a popup window with a form inside, allows you to upload a file, display its content in a textarea and send it (the content of the file as a string) to the server via an ajax request. That was the easy part. What I want to do now is to access that data sent through ajax (the string containing the data of the uploaded file) in Java because I need to run it through some validation. I had a good look around, including the book of vaadin, and the net in general and considering that I have never done this before, it seems that one way could be to have a connector, but it looks a little too complicated and also it appears - from what I understand from the book of vaadin https://vaadin.com/docs/-/part/framework/gwt/gwt-overview.html - that I won't be able to implement that in my project given the structure I have - which is different from what's in there. So, my question to you guys is, given the project I have (just a normal maven project) what would be the easiest way for me to access this data from Java? Here is some code from the project, to put things into context:

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);
}

Link to pastebin here http://pastebin.com/mSEJq0HT So, postData contains the string that I passed to the server and that I'd like to access in Java. I came across this earlier on, which may or may not be another way to deal with it vaadin with ajax. What do you guys think? Any help would be much appreciated, thanks

Community
  • 1
  • 1
antobbo
  • 255
  • 1
  • 4
  • 21
  • Don't mess with the Vaddin Client<->Server communication. Just add a `valueChangeListener` to the corresponsing field on java side and you get informed when the value has changed. – André Schild May 25 '16 at 08:12
  • is this a reduced example? if not, why even bother with vaadin at that point, when all you do is sending some humongous blob concated JS strings down to the client to steer some jquery for sending a file to another endpoint? otherwise, why not use a vaadin Window, Upload, TextArea...? – cfrick May 25 '16 at 08:37
  • all valid points guys, but the resaon why I'm using vaadin is because I'm learning and at this point I feel a bit more confident with JS than I do with Java/vaddin components hence sending all that JS string. Agree it would be better with upload, textAreas etc, but that will come when I refactor it, after I feel a bit more confident, that is. For now, I thought I'd understand the principles of using RPC etc, that's why I'm doing it this way even if it's not the best way... – antobbo May 25 '16 at 09:17

1 Answers1

0

Well, firstly I need to express my deep concern that you are using wrong tools in a really strange way to achieve your desired effect. I won't go deeply into that topic but lets just indicate the main purpose of Vaadin framework is to allow developer to write components in Java (similarly to Swing components) to avoid JavaScript mess. Yes, you can run JavaScript using Vaadin Framework but you should avoid it as long as possible.

Ok now lets get into hacking. You have two options to catch your file data (which is a String as you said) by your server:

a) Get rid ofconstructing your XMLHttpRequest by hand. Let Vaadin handle it for you. Instead of

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

just call JavaScript function, lets say

sendFileContentToTheServer(postData)

Now next thing you need to do is to register JavaScript callback on the Server side (read: Vaadin). Somewhere in your code (doesn't really matter where, just make sure the code is called at least once - ideally exactly once) put:

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)
    }
});

That's it. Vaadin will manage the RPC call for you. Your page won't be reloaded and you will get your data on the server side.

b) The second approach it's a way more tricky. It is technically possible to construct XMLHttpRequest by hand and receive data on the server using Vaadin. What you need to do is to register JavaServlet (not VaadinServlet). Send the data to the JavaServlet. Then through some proxy or reference call the existed VaadinUI. It's a compilcated way of doing things that you've already made very tricky so I won't go deeper into that.

kukis
  • 4,489
  • 6
  • 27
  • 50
  • thanks for that. As for your concern, yes you're right, but like I said before, the plan is to, at some point soonish, to refactor that, get rid of all that js and replace it with java code. I have to implement this with ajax I'm afraid. I also have a question about the 1st solution.In the book of vaadin they use a javascript connector to get the js to talk to the java part, and then they register the RPC and I was wondering whether that is an approach to consider? – antobbo May 25 '16 at 19:57
  • You could also do that. But it would be just a way more work. It requires at least good knowledge of the Vaadin framework and also you would need probably to recompile widgetsets in order it to work. I haven't covered this in my answer because it just add a noise to your code. Should you have more complex ui components and robust integration with JavaScript then that would be the way to go. For now you don't need it. Regarding your need of Ajax -did you know that RPC wraps Ajax, so in the end you still technically end up with a ajax request. Read http://stackoverflow.com/questions/13735602/ – kukis May 25 '16 at 20:35
  • thanks. Using RPC calls would be quite interesting in fact. Also, I need to get used to them as I will be using them a lot in the future. I'm reading various tutorials online to get this accomplished and I will post again, probably in a separate thread as I'm updating my code significantly. As for the good knowledge of the vaadin framework, I need to learn, so I might as well... – antobbo Jun 01 '16 at 14:24
  • Good to hear. Just FYI, if you find that my answer is valid for your question and it helped you to solve your problem, you may want to accept it / upvote it. In this way you contribute to community. – kukis Jun 01 '16 at 17:13