Access GWT Form Values from Spring Controller - java

I have started learning GWT and I would like to know if it is possible to create a form in GWT for a process such as user registration and then, handle the logic of the registration(extra validation, adding the data to the database, etc) in a spring controller. I have so far been unable to find resources on the web to do this, so I am guessing that what I am after might not be possible. Can this only be done using classes which extend the RemoteServiceServlet as shown in this video tutorial?
I have tried to access the data from my spring controller using the request.getParameter() method calls, what I noticed was that when I used the Post method, I was unable to access the form parameters, but when I use Get, I can access them. This is some of the code I am using:
GWT:
HorizontalPanel hrzPnlname = new HorizontalPanel();
hrzPnlname.add(new Label("User Name: "));
final TextBox txtUserName = new TextBox();
txtUserName.setName("userName");
hrzPnlname.add(txtUserName);...
Spring:
#RequestMapping(method = RequestMethod.POST)
public ModelAndView helloWorldFromForm(HttpServletRequest request)
{
Map<String, Object> model = new HashMap<String, Object>();
System.out.println("------>\n\n\n\n\n\n" + request.getParameter("userName") + "\n\n\n\n\n<-------");...
I am using GWT 2.4. Any information on this would be highly appreciated.
Thanks!

You can share data between GWT client and spring controllers in a several ways:
REST/JSON request
See how:
Calling REST from GWT with a little bit of JQuery
See also original GWT documentation(section "Communicating with the server/JSON")
This is the best way to communicate with a server in my opinion, because JSON is a pure standard protocol and it can be used by 3-rd party plugins(jQuery for example) and other web services.
Async GWT RMI(Remote method invocation), provided by Google
I think this is not the best idea to use GWT RPC, see why:
4 More GWT Antipatterns
Submit forms directly to spring controller as POST/GET request (as you trying to do).
See com.google.gwt.user.client.ui.FormPanel
I can reconmmend you to use forms submitting only for file uploading, because the browser will only upload files using form submission. For all other operations, form is not required in GWT, any request possible to implement using ajax.

Here are links to some resources - http://technophiliac.wordpress.com/2008/08/24/giving-gwt-a-spring-in-its-step/ and Experiences with integrating spring 3 mvc with GWT? .

Related

Apache Wicket - Custom servlet

I am trying to integrate Wicket (1.5.16) with the "Single Sign-On". In this process, IdP posts a bunch of attributes back to the Wicket application using HTTP POST.
If I use , it looks for life cycle and also adds some numbers to the form, etc. I am looking for the following solution,
1) Create a Servlet/Some Wicket class which can receive the POST requests.
2) If SAML authentication is successful, forward to a private Internal .
Please let me know if you have any submissions.
You can wrap Wicket in another Servlet Filter. This way your Filter will receive the request first and may decide whether to process it or pass it to Wicket.
To accomplish this you just need to define your <filter> above/before Wicket's filter/servlet in web.xml.

Should I be using #Controller classes when doing Spring web flow

It seems like I can do everything that the Controller class do inside Spring Web-Flow, for example decision making and switching from page to page. To my understanding, its the C inside the MVC model. Am I correct about this?
So my question is, is there any advantage to still include a Controller class when using Spring Web-Flow?
If you need access to the request and response, an appropriate design might still include a controller while also having a flow.xml. For example, if you had this code:
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getNativeRequest();
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getNativeResponse();
It's more intelligible to put that in a controller rather than a service.
Also, if you want to register a custom editor, it might make sense to have the controller have this logic in the initBinder() method.
Spring Web Flow uses the Spring MVC framework. The DispatcherServlet handles the request. A FlowHandlerMapping is used to map the request to a particular Web Flow.
Web Flow is to solve the problem involved with controller logic that spans multiple-page navigation (a pageflow, or wizard).
Web Flow can eliminate the need for specialized controller classes to accomplish following a path of page transitions/form updates along a predefined workflow. If you don't need to do this, you can save yourself a lot of configuration/complexity just by using MVC.

How to understand server/client data transfer in Angular, when coming from JSP?

I have a good basic knowledge of how to create web applications using java and jsp, together with Expression Language and JSTL. I am trying to learn how to use Angular.js for my front end.
I've gone through several tutorials, and I am starting to get a fair grip of the basics. But I have yet to figure out how to transfer data from the server, to the front end. Most tutorials I've found, describe how to send data from the front end, to the server.
I know that a RESTful api back end is recommended for Angular web apps. Unfortunately, I have no experience with this, and I find it hard to learn both angular and RESTful at the same time. If possible, I would love to make a work around, so that I can use my existing server solution, and learn one element at the time.
Server side setup
Now, in my old setup, using javax.servlet.http.HttpServlet, i call the service(HttpServletRequest, HttpServletResponse)-method. Inside the method, i add attributes to the request, like this:
request.setAttribute("attribute1", "1");
request.setAttribute("attribute2", "2");
request.setAttribute("attribute3", "3");
Then, because of a front controller pattern, I pass these request variables on to a redirect like this:
request.getRequestDispatcher("/WEB-INF/" + myPageVar + ".jsp").
forward(request, response);
For now, I would ideally like to keep this server side setup.
Current client side data access:
In the current setup, I can now access the initiated variables in two different ways. Either in a javascript script, like below (does not work with objects, only simpler attributes like strings (including JSON)). the next lines of code is picked from a jsp-page that the servlet would have redirected to.
var attribute1 = ${requestScope.attribute1};
or in the html, like this (would work with objects):
<c:set var="attribute1" value="${requestScope.attribute1}"></c:set>
I guess that I could incorporate Expression Language, and use javascript variables to initialize variables in my angular modules, directives and controllers, but I would prefer to do it purely in Angular.
Are these attributes accessible in any way, using angular? I've been trying to read up on $http, and $scope, but there is a jungle of non-relevant info on those, which I haven't been able to navigate through yet.
If the data you want to make accessible to angular should be ready when user lands on the page, it could make sense to put data in javascript variable in jsp page as you suggest.
Since your var is in global scope you can get in your angular controller like this:
$scope.att1 = attribute1;
However if you want to update your data without re-rendering the whole page (and that is what you want pretty soon) you should use $http to call a servlet that returns json. You can relatively simply make this servlet without jax-rs by overriding doGet in httpServlet and use a lightweight json lib (like gson). This example will do it:
//Set up pojo and make it into json string:
SomeClass pojo =new SomeClass();
pojo.setX("this is X");
JSONObject jsonObject = new Gson().toJson(pojo);
String jsonStr=jsonObject.toJSONString();
//Modify response and write json string
httpServletResponse.setStatus(200);//We are ok
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding("UTF-8");
Writer writer = httpServletResponse.getWriter();
writer.write(jsonStr);
writer.close();
//Thats it
In a simple setup you handle this response in your controller like this:
$http({method: 'GET', url: 'http://yourservleturl' })
.success(function(jsonStringFromServlet){
$scope.newData = jsonStringFromServlet;
})
.error(function(){
$scope.error = true;
});
In page-html you access the data with
<div>This is your new x: {{newData.x}}</div>
Don't use jsps at all, don't set attributes.
Only use static html, thats the benefit ! You can write angular directives that perform the funcationality of jsp includes, and have much cleaner code (no embedded jstl, java. just pure html).
Create server side code that returns json. Then your angular js code calls the rest api and populates the client side model.
If you have something that needs populating on startup, use javascript appropriately.
Here is a typical java method that returns json, using Jersey (similar to Spring MVC, resteasy, restlets, spark, apache cxf etc etc) :
#PATH("/myPojo")
#GET
public Response getPojo(Long id) {
Pojo pojo = myService.getPojo(id)
return Response.ok()
.entity(pojo)
.build();
}
In angualr you can then create, for example, $myPojoService.getPojo() that is injected to relevant controllers and calls this endpoint. When called it probably returns the pojo as json and then probably populates the $scope.model.pojo json object. Then the two way databinding of angular updates your gui ... and Boom, you are a full stack engineer/ front end dev!
There are a lot of different ways to accomplish this. This is just what I ended up using.
To expose values in your JSP to Angular you'll need to write them out in script tags and build up Javascript vars with them. Then you can access them from Angular. I'm doing this to pass-in authenticated user account information from server side to my angular code. Your JSP would contain code such as:
<script>
window.CURRENT_USER = {
id: <%=currentUser.getId()%>,
name: "<%=currentUser.getName()%>",
email: "<%=currentUser.getEmail()%>",
prevLogin: new Date(<%=currentUser.getPrevLoginAt().getTime()%>),
prevLoginIp: "<%=currentUser.getPrevLoginIp()%>"
};
</script>
Then in your angular controllers, you can access it like this:
var currentUser = $window.CURRENT_USER;
A better approach (mentioned by Jacob Nicolaisen) would be to use the Google GSon library to actually generate the JSON objects instead of hand coding them.)

Spring MVC webapp link to excel document and rename it

I have a question about whether or not something is possible. I have a spring mvc webapp that will have a button that links to an external website which returns an Excel document. The name of the excel document returned is rubbish and I would like to rename the document as it comes in before the user is prompted to save.
Is this possible using spring mvc. I'm on a really old version. The version compatible with Java 1.4.2.
So far I'm thinking that I'll extend org.springframework.web.servlet.mvc.AbstractController, override handleRequestInternal and then do something like this....
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
urlBuilder.setServerName(batchServerName);
urlBuilder.setPort(Integer.parseInt(batchServerPort));
urlBuilder.setContextPath(batchReportRoot);
urlBuilder.setServletPath(reportNameServletPath);
urlBuilder.setPathInfo(reportNamePathInfo);
urlBuilder.setScheme(HTTP);
String transitionUrl = urlBuilder.getUrl();
ModelAndView modelAndView = new ModelAndView(new RedirectView(transitionUrl));
return modelAndView;
But how do i take it further to rename the document as it comes in etc...
thanks
Perhaps another approach you might consider is that you have a Controller implementation that proxies the request onto the external website. Rather than interacting with the external website directly, your users interact with your Controller. This will give you the opportunity to re-name the file before it is served to your users. It also means that should things change in the future, you only need to change the implementation of your Controller.
So a proposed work flow could be:
User clicks link to your controller /downloadExcelReport
The request is handled by ExcelReportController
ExcelReportController makes an HTTP request to the external website and fetches the Excel document
Before returning the Excel report to your user, ExcelReportController sets the correct HTTP headers to ensure that the file is named according to what you need.
This way you're only providing a normal Controller implementation rather than having to override the internals of Spring.

Get http response as a String using spring

is their a neat way to pass a model to jsp, render the jsp and return the html as string using Spring. The html is then used in an e-mail that is fired off programmitcally, I do not want to use freemarker, but maybe I should ?
The url being requested is part of the same app.
I want one of my service layer classes to be able to call a view and use the html as a String.
You can call requestDispatcher.include(request, response) method.
You will need to implement the request and response objects. The request object will provide all information to the dispatcher which page should be rendered, the response object you will pass to the call will then capture the result to a string (using e.g. a StringBuilder).
See e.g. this tutorial for more info.
I'm guessing a servlet filter will do the trick? Not really a Spring solution, but easy enough to do.
Also this answer seems relevant, although it is DWR that you may not necessarily want to use in this instance.
You can use Velocity to create an email template:
String text = VelocityEngineUtils.mergeTemplateIntoString(
velocityEngine, "emailTemplate.vm", model);
There is a complete chapter in the Spring reference docs of how Spring can be used to send emails of various types.

Categories