I am building some sort of discussion board, where you can ask questions and write answers. Now I ran into a problem with routing and seem to be understanding them wrong.
I have a homepage called index, from there you can click a button "Ask question" or another button "Write Answer". Each button leads to another webpage (askQuestion.scala.html or writeAnswer.scala.html) where you can write a question or answer. After hitting submit you come back to the index-page, where the new question or answer is put into the view. In the background, the question / answer gets put into a DB.
My routes.conf:
# Home page
GET / controllers.Application.index()
#Questions
GET /FrageStellen controllers.Application.askQuestion()
POST / controllers.Application.sendQuestion()
#Answers
GET /AntwortGeben controllers.Application.writeAnswer()
POST / controllers.Application.sendAnswer()
But when I enter an answer, it gets written into the question-table in the DB! This is due to the fact that the question-route is higher up in the routing table and therefore it seems to get selected first.
This is against my understanding of routes, I thought a route consists of a 3-tuple: HTTP-Method, Request Path, Call definition ... and as the call definitions differ (sendQuestion() and sendAnswer()), the correct one should be used?
Why is this not the case?
I've read about routing in the documentation of the play framework and googled, but still dont understand.
I am also aware how to fix my problem, but I want to understand what's happening here.
Fix 1:
Change this
POST / controllers.Application.sendAnswer()
to this
POST /Antwort controllers.Application.sendAnswer()
Disadvantage: This is not the homepage (index) anymore. Seems weird.
Fix 2:
Write a combined method for sending stuff from the form to the index.
Disadvantage: I want to keep the methods separate, in order to maintain a better structure in my project. Also I would have to see if a question gets asked or an answer written and based on that omit one of the fields or use another one (answer has an extra questionID-field to link an answer to a question).
So, why is this happening in the routes and whats the best way to deal with it?
In Play each route is combination of route method (GET/POST) and path (determined by static parts and params types) so if you have two routes with the same type and path only first will be resolvable, other will be ignored even if you'll use other name of param (but same param type).
In this case the bar(String bar) method won't be resolved ever:
GET /foo/:foo controllers.Application.foo(foo: String)
GET /foo/:bar controllers.Application.bar(bar: String)
The safest way to make sure that you won't mishmash the routes is using unique paths always in sets:
GET / controllers.Application.index()
GET /FrageStellen controllers.Application.askQuestion()
POST /FrageStellen controllers.Application.sendQuestion()
GET /AntwortGeben controllers.Application.writeAnswer()
POST /AntwortGeben controllers.Application.sendAnswer()
Finally if you want to go to the root page after post you can return a redirect() instead of ok()
You should post to an action with different request path and then redirect to index. It is a recommended approach in web development.
http://en.wikipedia.org/wiki/Post/Redirect/Get
Related
This question already has answers here:
Design Patterns web based applications [closed]
(5 answers)
Closed 6 years ago.
EDIT: I have posted a somewhat shorter and revised question here: Java web development: transfer control from one servlet to another while passing the request object (Version 2)
As more or less a beginner at Java web development, I’m unsure about how I should structure the flow between servlets/pages when a form is submitted (POST). It’s an elementary issue, I suspect this may be an easy question to answer for the experts. (Still, my book and some googling didn’t deliver a clear answer.) My question is a bit long, and that's because I want to make it clear where I'm coming from. Thanks for you patience.
Let’s say we have two servlets A en B, with each having its ‘own’ .jsp-page; let’s call those pages a.jsp and b.jsp respectively. Now as long as there are no forms on either page (i.e., no POST method used), it’s clear how things should go. That is, before any .jsp-page is shown, the corresponding servlet is activated, doing some preparation for the .jsp-page by setting the relevant data elements (most notably, as attributes of the request object) that the .jsp-page needs, then forwarding the request object (etc.) to the .jsp-page, which then actually displays the page with the data. So for example, a link on page a.jsp may link to the servlet B, and on clicking that link a GET-request for servlet B is triggered, which then does some preparation (setting some request attributes), before forwarding to its ‘own’ .jsp-page (i.e. b.jsp).
But now let’s assume that page a.jsp displays a form with a submit button, method=”POST” and action=”B”. Then yes, servlet B is activated, and this servlet has to determine whether the data entered by the user is valid. If the data is in fact valid, we can simply forward to b.jsp, no problem there. But what if the data is NOT valid?
In that case, we obviously want to show a.jsp (the form page) again, with the data that the user entered the first time still present. One way to achieve this, is to simply have servlet B forward to a.jsp (thus bypassing servlet A). However, there is a big problem with that: the URL shown to the user, in the address bar, will still read “……/B”. So the user will see the correct page (i.e., a.jsp, containing the form), but with the wrong URL (/B). So for example, if we take “Register” and “ThanksForRegistering” instead of “A” and “B”, the user will see register.jsp – but with URL “……/ThanksForRegistering”! Not good.
And calling ‘include()’ instead of ‘forward()’ on the request-dispatcher doesn’t seem to work either. If we do that, not only does it result in a GET-request (as opposed to the POST-request we want), but we actually lose the whole (original) request-object with its attributes (which we need, after all, to re-populate the form). At least, that’s what my own experimentation seems to show. So using ‘include()’ doesn’t seem like a viable option at all.
Another obvious idea is to have "action=A" (instead of "action=B") for the submit. Then the servlet A itself can handle the validation, and if validation fails it can simply forward to a.jsp again, no problem. BUT then what if validation succeeds? Then we want to show the follow-up page b.jsp, but that page may well need the attributes from the original request-object (from the form-submit) again; for example, to have the user check that his entered data was in fact all correct. So basically we have the same problem as before, but with the roles of A and B (and their respective .jsp-pages) reversed. So this doesn't seem like a real solution either.
And I don’t see any other alternatives.
So basically, I’d simply like to be able have one servlet give control back to another servlet, but with the request object being passed from the former to the latter servlet. Or, if that’s not possible, I’d want to be able to forward from servlet B to a.jsp directly, but with the correct URL shown to the user. Or any other way to accomplish what I want.
Many thanks.
I think that the assumption that there has to be one page per servlet is causing the problem here....have one servlet which based on input redirects,forwards or includes a particular page....you dont really need to always invoke a different servlet for a page.....you can have a single front controller with a view resolver the combination of which will redirect or forward to a page.
You can use filters to achieve the same thing or think of setting attributes in HttpSession if validation is successful and retrieve the data in all the pages whenever it is required.
session.setAttribute("object", object);
I hope this is what you are looking for.
Is there any way in java to make code: Example if someone clicks on skipAd on adf.ly link Int will increase. Example 2: I click the button, it will take me to a adfly link. and when i click skipAd on adf.ly: in the app int will increase for 1(int++).
Is there any way to do that?
First of: StackOverflow hates it when people come here showing that they have taken zero effort to find a solution for the problem.
Secondly:
Your question is very unspecific.
Are you and your friend on the same network? If so, you might want to consider using ARP-Poisoning in order to inject custom JavaScript into the webpage that will function as an EventListener. Obviously this will only work if he is visiting AdFly via an HTTP connection and since Adfly-Links are generated with an HTTPS prefix, you will rarely find people using HTTP (despite the fact that they still don't enforce HTTPS, grumpf).
There are probably tons of other solutions but they will all involve tinkering with his/your webtraffic. And no offense, but I feel like you should probably learn some more Java before taking on such a big task.
More than in 'java' it would be easier to do it in 'JavaScript'. You'll have to monitor the onClick event of that SkipAd button and then you can increase your counter.
I advise you to make your question even more clearer in why-you-have-to-do-it department to avoid down votes
Summary - Want to make a simple website form filler. The website is NOT mine and I cannot edit its source code. Don't know what tools/languages are needed. Would java, jsp, html be enough ?
Request - Please reconsider your decision to close or downvote. I only need to know if java is enough or not.
There is a form on a website, say for reserving a visit to only one dentist. You fill your details and the date and time you want to visit. Then, it tells you if an appointment can be made or not, somewhere in the webpage.
This web page is NOT protected by CAPTCHA. I don't want to enter my details all the time to look for a reservation. I want to make code to do it for me.
I want to make code which will -
1 - Fill the details into the form and "press" submit.
2 - Then, read the resulting page and find out if a reservation is
available or not. If yes, do something like maybe - pop up a GUI
message, send e-mail or whatever.
3 - Repeat the above steps every 5 hours or so.
What are the languages and tools I would need to do this job ? Would I need more than java, jsp and html (thats all i know now) to make such code ?
Thanks.
I will suggest you try CURL. That will make you solution more simple in my opinion.
You can execute HTTP GET/POST with CURL, which is enough to solve your problem. Give it a try, and if you get block you can ask a more specific question about CURL or HTTP.
Hope it helps.
IMO, If you really just want to fill up some forms to check a reservation, no need to code anything, why not just install a plugin, Selenium, record your actions there and just run it at specified times: http://docs.seleniumhq.org/
Sure.
You need a web server and a database on the back end.
Since you feel comfortable with Java, JSP/HTML would probably be an ideal solution.
IMHO...
I have a simple html page with the purpose of performing changes to an entity which is written to the database. The page has two forms:
GET: select the entity to change
POST: process the changes to the entity and write it to the database
When the POST action is performed I want to display the same page again, in addition I want to keep the entity parameter as set by the GET action. Currently I am doing the following at the end of the doPost method:
response.sendRedirect(path + "?entity=" + entityValue);
Which works perfectly fine, but after reading the differences between forward and sendRedirect I thought I have to use forward, but that won't work since the doGet method will not be executed as with sendRedirect. So is my approach correct or should this solved in another way?
Your approach is excellent. It uses the post-redirect-get pattern, which has several advantages:
clean URL that is bookmarkable and can be sent by email for example
no risk of resubmitting the modification by hitting the Refresh button
clean navigation through the browser history
separation of responsibilities between the get and the post URLs
So keep everything as it is. A forward is a less optimal solution than a redirect in this case.
I'm trying to make something simple with Stripes. I've read and heard a lot about easiness of using this framework and about steep learning curve (i.e. learning is quite fast and productive).
But till this moment I can't even create the simplest HelloWorld with Stripes.
All examples I've found demonstrate functionality like: "click on the link --> see the result". When we click on the link special handler is called (which returns Resolution) and after that getters also works (because bean is instantiated).
But if I don't want a link but I want simple static information (for example, when I open StackOverflow I don't need to click a link, but I immediately see a list of questions) then it's something non-trivial for Stripes as it seems to me, because bean is not instantiated immediately.
How to fix that? Are there some special annotation or another technique?
Have anyone here tried Stripes and met the same problem? I'm realy frustrated, maybe I've missed something..
UPD: it's probably not clear because I haven't appended any code. So I describe a bit more. In order to reproduce my situation it's enough to get the code from QuickStart and try to retrieve text from ActionBean getters (currently, text is hard-coded in jsp). The text will appear only after you press the button (i.e. after handler does some work). But after you open the page first time you won't see the text.
Are you familiar with the MVC pattern( see http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller )? One of the key parts of the MVC is you never ever call the JSP directly. You don't go to www.myservername.com/myjsp.jsp. Instead, you go to www.myservername.com/mything.action. Stripes will do some processing, set some stuff, and then send you on to the specific JSP.
From your question, it just sounds like you are trying to go directly to JSPs. Stop doing that, and you will get along much nicer with stripes.
As for what happens when you just go to www.myservername.com, you go to the welcome-file in your web.xml. You do something like this
<welcome-file>index.jsp</welcome-file>
(yes you break the rule about no jsp directly)
Then in index.jsp you make it a 1 line file like so:
<jsp:forward page="myaction.action"/>
And the first time someone goes to your site, they hit index.jsp, which sends them to an action, which populates stuff and forwards them on. In no other cases will the user directly get to a jsp, and the index file is nothing but a forward to a real action.