spring controller call from javascript. annotations with spring - java

Is it possible to call a spring controller from javascript included in a jsp?
I'm trying to call it like this:
form.action='${pageContext.request.contextPath}/spring/myController';
I can see that the control passes throught the lines, but nothing is happening.
Also I get messages like get or post is not supported.
when I submit the form with a post method I get error message post is not supported.
I use the annotations like this in controller.
#RequestMapping(method = RequestMethod.GET)
How can I handle both get and post in spring controllers?

Your javascript is not actually calling anything. Rather, it is setting the "action" attribute of (I assume) a <form> element in your web page to some URL assembled by the JSP. The "call" to your server will happen later ... when the user clicks some button that causes the form to be submitted.

Related

How to set an attribute in a jsp page with hyperlink (request scope)

I think the title above is a bit confusing.
What I'm trying to achieve:
I have a jps page(located in WEB-INF) with a hyperlink in it that will call another jsp (in WEB-INF) via servlet.
I understand that this can be achieved using the following:
Go to this page
But because there will be lots of hyperlinks, my idea was to have a general servlet(OpenPagesServlet) to handle all those pages.
Something like this:
JSP page:
<% request.setAttribute("page", "page1.jsp");%>
Page 1
OpenPagesServlet in doGet method:
String page = (String) request.getAttribute("page");
request.getRequestDispatcher("/WEB-INF/" + page).forward(request, response);
I tried the code above and I get:
HTTP Status 404 - Not Found
type Status report
messageNot Found
descriptionThe requested resource is not available.
But if I try with session.setAttribute / sesion.getAttribute the code works fine, but I don't want to have sessions on each time I click on hyperlinks.
The other approach I found was to use:
Page 1
and inside the servlet:
String page = (String)request.getParameter("value");
request.getRequestDispatcher("/WEB-INF/" + page).forward(request, response);
It worked, but this approach is not good because the page can then be accessed directly using the url:
http://localhost:8080/WebApp/OpenPagesServlet?value=page1
So...my question is why request.setAttribute/request.getAttribute is returning 404?
Is there a different approach to achieve what I'm trying to do?
An HttpServletRequest and its attributes only live for the duration of one HTTP request/response cycle. After yo've set the attribute in the JSP, the JSP is rendered and sent as part of the HTTP response body. The Servlet container considers the request handled and clears its attributes. The attribute is now gone.
It is therefore no longer available in the next request that arrives after the user clicks the link.
The session attribute or request parameter is fine. Consider looking into the Front Controller pattern.
Also, consider using the core tag library (in particular the url tag) instead of scriptlets for constructing your links.

Calling Bean method from Jquery

Is it possible to call Bean from Jquery? My requirement is like below,
I have a JSF 1.2 based Servlet.
Am invalidating a user's session if he is idle for some time. Am showing Jquery dialog box 1 minute before invalidating the session. A user has 2 options in the dialog box. "Yes I want to continue" will extend the session. "No I want to logout" will logout the user.
When user clicks on "No I want to logout", I want to call bean method where I update the Database & invalidate the session.
Below is the code,
'No, Log out': function(){
$j.idleTimeout.options.onTimeout.call($j.post('//This is where am stuck',function()
I want to call bean in $j.post so that I can do some clean up activities in my bean.
How this can be done?
Regards,
You can either use just use a hidden(style="display:none") commandButton with an action pointing to a method in your bean , and call a .click() on it from jquery
something like this
<h:commandButton id="myButton" action="#{myBean.myInvalidateMethod}" style="display:none"/>
jquery
&("#myButton").click();//possible myForm prefix appear before the id so use #myForm\\:myButton selector
Or you can call servlet from your jsf page , similar to this answer Calling a Servlet from a JSP page using jQuery Ajax
You can't directly access the methods, you'll have to make your servlet handle your request and call the method for you and return the data in json format for example

How to generate success alerts in jsp after successful execution of a servlet?

I have a jsp page which contains a form which calls a servlet, after inserting data into the database by a servlet hot to display successs alert to the user on the page?
Thanks in advance for answering.
Either you call the servlet asynchronously with AJAX and have a success callback function (see jQuery example: http://api.jquery.com/category/ajax/ )
Or you do it the old fashioned way with a synchronous Post which loads a success page, or the same page with for example a query parameter that states that you have succeed. This could then be used to activate a script block in your JSP (or whatever template language is your flavour).
You can use a javascript alert box. See http://www.w3schools.com/js/js_popup.asp

Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?

Is there a way to attach a global listener to all AJAX calls in JSF? Maybe through a phase listener or something?
Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. Then you come back and click a button that has an f:ajax attached to it. The server will respond with a 302 redirect to the login page.
The user sees nothing. They can repeatedly click and invoke the ajax call, but to them the app is just "dead."
So, my though is, is there a way to attach a listener to all ajax calls in JSF? If so, what I'd like to do is monitoring the response code. If it's a redirect, use a window.navigate to send them along their way.
I'm always open to hear how others have solved this problem!
Is there a way to attach a global listener to all AJAX calls in JSF? Maybe through a phase listener or something?
Yes, a PhaseListener can do it. A SystemEventListener also. A Filter also.
If you're inside JSF context, then you can check as follows whether the current request is an ajax request or not.
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// It's an ajax request.
}
If you're not inside JSF context, e.g. inside a Filter, then you can check as follows whether the current request is a JSF ajax request or not.
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// It's a JSF ajax request.
}
Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. Then you come back and click a button that has an f:ajax attached to it. The server will respond with a 302 redirect to the login page.
The user sees nothing. They can repeatedly click and invoke the ajax call, but to them the app is just "dead."
Forcing a redirect on an ajax request requires a special XML response. When you're inside JSF context, then ExternalContext#redirect() already takes this implicitly into account. All you need to do is to write this:
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
If you're not inside JSF context, e.g. inside a Filter, then you'd need to write the whole XML response yourself. E.g.
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url);
To redirect a jsf ajax request you need xml as follows
<?xml version="1.0" encoding="UTF-8"?>
<partial-response>
<redirect url="XXX">
</redirect>
</partial-response>
Here XXX is url you want redirect to happen.
On ajax call redirect sent is not as above hence no redirect.
To get the desired result have a filter for all jsf request except few
pages(login page) and check session is valid and if it is really jsf
ajax call by checking header "Faces-Request", its value should be
"partial/ajax". If session has expired and is ajax request send above
xml as response.
It should work.

Call a controller method within Play! template

How can I call a controller method from within a Play! template?
I have a default controller, Application, and the hasliked() method inside that controller.
The method returns whether the logged in user has liked the post ID.
It returns "none" if the user has liked the post, otherwise it returns "block" (for the CSS)
I have added the following route: GET /hasliked/{id} Application.hasliked
I tried the following:
#{list items:postList, as:'post'}
%{
display = Application.hasliked(post.id);
%}
<div style="display: ${display}">...</div>
#{/list}
But I get this error:
Template execution error
Execution error occured in template /app/views/Application/dashboard.html. Exception raised was NullPointerException : Cannot invoke method hasliked() on null object.
Try using a fully qualified name like:
controllers.Application.hasliked()
EDIT on comment:
The issue with your exception is that you are accessing the controller to get a value. That's wrong.
Controllers in Play are used to navigate. They are static, they return "void", and they do a call to another controller method or to a render method. What you try to do may have unexpected results.
What you want to do is to get the value inside the controller and pass it as a parameter:
//On controller
public static void yourRequest() {
//...
Object display = getDisplay(); //get your value
render(display);
}
//On template
<div style="display: ${display}">...</div>
That's the recommended way.
The exception you get is (most likely) caused because your Application.hasLiked() ends up with a redirect call (either render() or call to another controller's method) and that's happening while you render the page corresponding to the initial call. So it breaks.
It would probably be a better way to do fill the information that is required into the list of items instead of calling back the controller:
Your template doesn't need to know about your controllers. It should just convert data to HTML and not acquire data from somewhere else. That's the task of the controller.
It would also be more efficient in terms of database access to fetch the like status for all items at once instead of doing several calls.
When doing refactoring (e.g. renaming methods etc of your controller) the IDE cannot help you if you call controllers from the template (unless it's aware of how Play! templates work).
If you really must do this (and again, you shouldn't) you need to fully qualify the name of the controller:
controllers.Application.hasLiked()
just like Pere Villega pointed out.
An alternative to this may be to issue an AJAX call to set the style, rather than using the controller.
Set the style of your "liked" element to display: none by default, and when your view has rendered, issue an GET request to /hasliked/ with the ID as a parameter and update your CSS styles accordingly: when the user has not already liked this, output false (or whatever you want), so that you can use JavaScript to re-define the style.
The easiest way to do this would be to use jQuery to issue a request to your controller when the view has loaded. Have a look at the Play! documentation on AJAX for some inspiration. Note that you don't have to use #{jsAction /} at all - personally I find it easier to define the jQuery calls myself.
Try the following:
<script type="text/javascript" language="javascript">
var url = "#{Application.hasliked}" + "/" + yourId;
window.location.replace(url);
</script>

Categories

Resources