Post Form to a page in CQ5 - search

I have a custom search component which searches for some parameter(s) from a dropdown [myParam] and displays the search results in another page. I currently use the default (GET) form
<form id="searchForm" action="/content/myWeb/searchResult.html" method="get" target="_blank">
In the result page, a component picks up the request params and processes the search.
I need to make it a POST submission so that the search parameters are NOT visible in the URL. But if I make it a method="Post" in the form above, I get this error:
Status
500
Message
javax.jcr.nodetype.ConstraintViolationException: no matching property definition found for {}myParam
Location /content/myWeb/searchResult
Parent Location /content/myWeb
Path
/path/to/search/page

That exception is the incidental way that Sling tells you that the servlet to which you are attempting to POST can not be found. What happens, in this case, is that Sling defaults to the SlingDefaultPostServlet, which attempts to to POST properties (represented by your form values) to the node /content/myWeb/searchResult. There's no way for Sling to say "I can't find a servlet that's registered to your request", so it just falls back to it's default behavior.
I'm assuming /content/myWeb/searchResult is a cq:Page node type. That node type is very restrictive, which is why it tells you that you cannot add properties that correspond to your form values.
This worked before, because your GET request to /content/myWeb/searchResult.html was able to resolve and execute. All GET requests to a page node can be served up by the system, inherently.
Now, since you are trying to do a POST, you need to create and register a new servlet that can handle this POST request. To do this, you'll need to create a SlingPostServlet and register it to your specific path (not recommended) or a specific selector/extension combination (recommended). That servlet should process the request parameters and respond with an HTML document.
A caveat...
What I just described will help you technically build what you are asking. That said, I don't agree with the premise that you should "make it a POST to hide the request parameters." The reason this is so much extra work, is because you are circumventing the principles of REST, which Sling is theoretically built to support. Your URL (via request path and parameters) should be communicating "I want the page at /content/myWeb/searchResult, given the criteria param1=x, param2=y, and so on". The GET with request params is an appropriately RESTful request.
I suggest you rethink what you're trying to do. Building a more complex solution around RESTful principles is not a good practice.

Just as a sidenote, you can always check if a given URL is bound to a servlet via the sling servlet resolver. Reachable via the OSGI-console or via URL:
http://localhost:4502/system/console/servletresolver
This can at least help you find closure on, if the servlet is registered to the given URL.

You can create a POST.jsp for your page, which could handle the POST request.
It is not restful to make get like request with POST, but sometimes it can be useful. Also With POST, dispatcher won't cache your request.

Related

RESTful service using only GET and POST methods

RESTful services are implemented currently with GET, POST, PUT , PATCH and DELETE
or at least using 4 of that. (usually method PATCH is not used).
Is it possible to implement a RESTful API using only GET and POST
making the post behave as a POST, PUT or DELETE, depending on some parameter passed in url or headers or just as that article mention doing a semantic url like:
/users/delete
/users/update
I was searching something like that and found that article but it is not very complete and is a little old.
https://www.infoq.com/news/2010/06/get-post-alone-restful
I know that in some web frameworks (like Django) they only allow method POST and GET, but i think this occur for compatibility reasons, with previous versions of the framework.
In one hand Fielding talking about restful services the unique restriction is about semantics, but using the example above we have a sematic use ok.
Without ambiguity between a POST or PUT or DELETE.
Yes, it is possible and it is even often done in practice for some specific use cases - for example because you can only use GET and POST in HTML forms, or when you need to have "PATCH" but it is not supported by the clients that you need to cooperate with.
If you use Express, there is method-override module:
https://github.com/expressjs/method-override
that lets you have an HTML form like:
<form method="POST" action="/resource?_method=DELETE">
<button type="submit">Delete resource</button>
</form>
that would delete a resource instead of posting it.
The method override is usually done with a query parameter like "_method" above or with a special header like "X-HTTP-Method-Override" that can be set to "DELETE" or "PATCH" or whatever you want.

Is there any way to identify if type of an HTTP request is changed by the intercepter?

Is it possible to validate if an HTTP request originated from the client as GET, but was intercepted in between and converted to POST, or vice versa?
It is one of the security validations that is required as part of the project I am working on, but not getting enough clue about it. One of the way we thought of using as validation is to check if it is a GET request with a body than it could be POST. But that is just one case. Also if a POST is changed to GET by forging the request, I believe the data in the body can also be removed.
edit: Added more information about application and the intercepter
It is a regular Java web application developed using Struts with JSPs on the client side. The request from the web pages are being intercepted using Burp Suit Proxy to change the payload in the request.

Post to external URL and show page

There is a requirement in the webapp I am developing (not changeable unfortunately ) that states that I have to send via post certain parameters to a servlet from a JSF managed bean. That servlet then forwards to a page where it shows some of the parameters sent via POST in a form for the client to see.
That servlet is part of an external application, thus I cannot use RequestDispatche.
I have tried Apache Http client but i get to a point that the post URL responds with the content of the page (i can actually see the HTML in my logs), what i would like to do is forward to the page not receive it as answer in my code.
If this makes no sense let me know :).
EDIT:
what i need to do is:
JSF BEAN->POST data to an external servlet -> Follow servlet redirect/forward to an external page
One way I'm thinking of doing this is forwarding to an internal facelets or JSP page that builds a hidden form with all required parameters and automatically submits it to the post Servlet
So after trying to find other ways to do it, I have decided to go this way:
Create an internal page, with a hidden form that will be automatically committed with a small javascript.
Get all required data in the bean, navigate to page, fill hidden fields with the required info, post to external servlet.
I should also say that a better way to do this kind of interaction would be:
Post data to servlet (for example using apache http client)
manage the servlet response (for example 200 OK)
navigate via GET (using a redirect) to the servlet by passing some id as a
get parameter through which the data can be shown in the page
This would require the servlet to accept POST and get requests, and also to have a way to get the data sent via post when it's called via get. This was not the case for us.

Node validation in jade template

I'm extremely new to node.js, and have years of experience in PHP, so my thinking about the issues below, might be tainted by my backed ways.
I'm currently using node set up with foundation CSS, and using their reveal modal windows to display most of my forms. I want to avoid re-displaying them upon submit, and instead, validate them on client side.
Basic user creation will have fields as per below:
name
email
password
password confirmation
Form my basic validation i can use require to validate the input,
input(type="text",name="user[email]",placeholder="#",required)
but I would also like the client to check if the email already exists after the user types it in, and whether the passwords are correct.
I've been reading about the validator module but from the documentation I read about it, I only understand how to validate the values after they've been posted. I've seen the express-form module as well, but It's no longer maintained, so I would rather avoid it.
Could someone point me in the right direction?
I don't have any experience with validator or express-form, and I am not sure you need them for what you are trying to achieve. Most of what you are trying to do will be client side work (e.g. jQuery Ajax calls to validate the data) That kind of client-side code should be pretty much the same regardless of whether you use a Node.js backend or a PHP backend.
Injecting the initial JavaScript in your Jade page should be pretty straightforward once you figure out the proper syntax to include JavaScript in a Jade page. The wiring of DOM events on the page to make Ajax calls (onClick, onTextChanged, et cetera) will be conceptually the same as if you were writing a plain HTML page.
In your Node.js server side you'll need a route to handle the request to validate if an e-mail address already exists and that code very likely will return JSON that you will use in your client side form to display the results of the validation to the user. But that should also be very similar to what you would have done with a PHP backend.

Is there a way to have a JSF page automatically update a webpage when bean values change?

(Using JEE6) Is it possible to have a webpage automatically update (or listen) to values from within a bean/class and display them on the JSF when these changes happen?
As KayKay mentioned you can implement some sort of polling methodology using javascript to ask the server periodically to send updates if there are any. And unless you use ajax you will have to be content with only complete page refreshes.
JSF as good as it is, sits on top of basic stateless web technology. As such unless you use Ajax or some custom code the server will only respond to a request from the client. Some libraries like icefaces have incorporated a "push" component that allows what you are looking for (from what I understand, this is a fundamental part of icefaxes). That is, to push server side changes to the client.
You have to set up a listener on your end so that your bean will be notified when a value change happens on the server (like in your backing bean which is on the server). When the change happens you can ask say, 'icefaces push' (or another library like primefaces, which you indicate you don't want to use) to send a notice to the client. The client side code (usually ajax/javascript) will process the notice and then send a request for the whole object per normal request response. That is the notice tells the client something it's interested in changed so the client can ask for an update. Aside from the notice, still request/response.
I mention icefaces push because it seems to be the favoured library for this now. But others have this as well. I don't believe the standard JSF 2.0 AJAX libraries have this.
Here are a couple of resources to look at:
(The video is a good start to get the idea of what is going on, then use the rest of the site)
http://www.icesoft.org/demos/icepush-demos.jsf
Older but I think still relevant IBM tutorial on what you want to do, using inventory changes as an example:
http://www.ibm.com/developerworks/web/library/wa-aj-dynamic/index.html
And another stack question related:
Is there a better Ajax Push for JSF 2.0 than Icefaces
Unfortunately it looks like you cannot do this with just JSF, you will have to use one of these libraries or even harder, roll your own push mechanism.
I don't know of a JSF feature to do so. I would simply do some javascript polling, using for example jquery load method to refresh the parts of the page where the values are displayed.
It would help to know what you want to do : refresh the whole page when there is a change, update somes values that are displayed from the start, or add new values to the page.

Resources