Redirect in badrequest - java

I have a problem.
I have form in play framework and when I want open new, I use this link: link/projeto/novo
There are some fields that I need to save and I do one validation and If there some field blank, I send one "badrequest", like this:
public static Result grava() throws IOException{
Long id;
Http.Request request = request();
Form<Projeto> projetoFormRequest = projetoForm.bindFromRequest();
listaDeErros = new ArrayList<String>();
Projeto projeto = projetoFormRequest.get();
if(StringUtils.isEmpty(projeto.getNomeProjeto())){
listaDeErros.add(Messages.get("projeto.form.validacao.nomeProjetoObrigatorio"));
}
if(projeto.getTipoProjeto().getIdTipoProjeto()==null){
listaDeErros.add(Messages.get("projeto.form.validacao.tipoDeProjetoObrigatorio"));
}
...
if(listaDeErros.size()>0){
return badRequest(cadastro.render(projetoForm, listaDeErros));
}
...
My routes:
GET /projeto/novo controllers.ProjetoController.cadastroProjeto()
POST /projeto/grava controllers.ProjetoController.grava()
but my link in browser change to link/projeto/grava
I'd like to maintain the same link link/projeto/novo
How could I do this ?
thanks

As you are returning badRequest() in the grava action it stays there... badRequest is a Result NOT a redirect.
You can try to redirect to the cadastroProjeto in case of error, anyway you'll need to pass projetoForm somehow, maybe using cache?
TIP: It's good habit to use English names for actions, models, views, etc - even if routes are Portuguese ;)

Related

Scala with Spray Routing - accessing GET parameters?

I'm currently working on an application built in Scala with Spray routing.
So for dealing with a JSON document sent over POST, it's pretty easy to access the variables within the body, as follows;
respondWithMediaType(`application/json`) {
entity(as[String]) { body =>
val msg = (parse(body) \ "msg").extract[String]
val url = (parse(body) \ "url").extractOpt[String]
However, I'm now trying to write an additional query with GET, and am having some issues accessing the parameters sent through with the query.
So, I'm opening with;
get {
respondWithMediaType(`application/json`) {
parameterSeq { params =>
var paramsList = params.toList
So, this works well enough in that I can access the GET params in a sequential order (just by accessing the index) - the problem is, unfortunately I don't think we can expect GET params to always be sent in the correct order.
The list itself prints out in the following format;
List((msg,this is a link to google), (url,http://google.com), (userid,13))
Is there any simple way to access these params? For example, something along the lines of;
var message = paramsList['msg']
println(message) //returns "this is a link to google"
Or am I going about this completely wrong?
Apologies if this is a stupid question - I've only switched over to Scala very recently, and am still getting both acquainted with that, and re-acquainted with Java.
What I usually do is use the parameters directive to parse the data out to a case class which contains all the relevant data:
case class MyParams(msg: String, url: String, userId: Int)
parameters(
"msg".as[String],
"url".as[String],
"userId".as[Int]
).as[MyParams] {
myParams =>
// Here you have the case class containing all the data, already parsed.
}
To build your routes you could use the parameters directives. I'm not sure if this is what you're looking for, anyway you could use them as:
get {
parameters('msg) { (msg) =>
complete(s"The message is '$msg'")
}
}
Spray directives can be easily composed so you can use combine them in any way you want.
I hope that helps you.

PactDslJsonObject getting resolved to Empty Map {}

The object, below, while debugging is being displayed as {} instead of {"types" : ["Ice Cream"] } as one would expect. Why is this happening.
PactDslJsonObject resquest = new PactDslJsonObject()
.array("type").stringMatcher("\w+","Ice Cream");
Sorry to answer my own question. Looks like we must close the children of PactDslJsonObject or whatever (could be an array as well in that case you will have to close the object withing the array.) is it that we would like to request or respond from aor to a service.
So, in this case it should be,
DslPart response = new PactDslJsonObject()
.array("type").stringMatcher("\w+","Ice Cream").closeArray();

Redirect with anchor in play 2

I'm looking for possibility to add anchor to url returned in controller:
public static Result open(String id) {
// here I want to add acnhor like #foo to the produced url
return redirect(routes.MyPage.show(id));
}
I found that it was possible in play 1 using addRef method, but I couldn't find any replacement of the method in play 2.
Of course I can use concatenation like:
public static Result open(String id) {
// here I want to add acnhor like #foo to the produced url
return redirect(routes.MyPage.show(id).url + "#foo");
}
But it seems ugly.
Thank you for any help! Have a good day!
Before trying to answer that question.
I should recommend you change whatever behavior you're currently setting.
Because, an URL fragment's purpose is client side only. Such fragment is never sent to the server, so that it's cumbersome to do the opposite.
However, here is the embryo of a (quite?) elegant solution that you could follow.
What I'll try to do is to leave the browser deal with the fragment, in order to keep potential behaviors (f.i. go to ID or even deal with history...).
To do so, you could add an implicit parameter to your main template which will define the fragment that the URL should have:
#(title: String)(content: Html)(urlFragment:Option[UrlFragment] = None)
As you can see I wrapped the parameter in an Option and default'ed it to None (in order to avoid AMAP pollution).
Also, it simply wraps a String but you could use String alone -- using a dedicated type will enforce the semantic. Here is the definition:
case class UrlFragment(hash:String)
Very simple.
Now here is how to tell the browser to deal with it. Right before the end of the head element, and the start of body, just add the following:
#urlFragment.map { f =>
<script>
$(function() {
//after everything is ready, so that other mechanism will be able to use the change hash event...
document.location.hash = "#Html(#f.hash)";
});
</script>
}
As you can see, using map (that is when the urlFragment is not None) we add a script block that will set the hash available in urlFragment.
This might be a start, however... Think about another solution for the whole scenario.
As of Play 2.4, it's possible to use Call.withFragment().
routes.Application.index.withFragment("some-id").absoluteURL(request)
This was added by PR #4152.

What is the better way of handling HTTP responce statuses?

HttpResponse response = mHttpClient.execute(mHttpGet);
if(response.getStatusLine().getStatusCode() == 201){
}
.....
I have different statuses and I need to handle all them to show later for appropriate status appropriate dialog message.
What is the better way of handling HTTP response statuses?
Another way is as follows:
Put these status codes and corresponding messages in a property file.
Your could do something like
staus_201= Message for status 201
When you receive a status, retrieve the corresponding message from the property files (see example )and display them.
The advantage of this is: for any new status, you won't have to do any code change. Just add the new entry in property file and you are good to go.
you can use switch case
int status = response.getStatusLine().getStatusCode();
switch(status){
case 201 : //do something ;
break;
so on...
default : //do something else;
}
First I would suggest to use symbolic names instead of "magic values" things like this:
int status = response.getStatusLine().getStatusCode();
if (status == HttpServletResponseCode.SC_CREATED) {
...
}
In this case it's really doesn't matter if you use if or a switch-case...but most important the code will be more readable by using symbolic names. (I'm not sure which library you are using...i assume every library will have such kind of constants like this.).

How to ignore HTMLUnit warnings/errors related to jQuery?

Is it possible to teach HTMLUnit to ignore certain javascript scripts/files on a web page? Some of them are just out of my control (like jQuery) and I can't do anything with them. Warnings are annoying, for example:
[WARN] com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument:
getElementById(script1299254732492) did a getElementByName for Internet Explorer
Actually I'm using JSFUnit and HTMLUnit works under it.
If you want to avoid exceptions because of any JavaScript errors:
webClient.setThrowExceptionOnScriptError(false);
Well I am yet to find a way for that but I have found an effective workaround. Try implementing FalsifyingWebConnection. Look at the example code below.
public class PinConnectionWrapper extends FalsifyingWebConnection {
public PinConnectionWrapper(WebClient webClient)
throws IllegalArgumentException {
super(webClient);
}
#Override
public WebResponse getResponse(WebRequest request) throws IOException {
WebResponse res = super.getResponse(request);
if(res.getWebRequest().getUrl().toString().endsWith("/toolbar.js")) {
return createWebResponse(res.getWebRequest(), "",
"application/javascript", 200, "Ok");
}
return res;
}
}
In the above code whenever HtmlUnit will request for toolbar.js my code will simply return a fake empty response. You can plug-in your above wrapper class into HtmlUnit as below.
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
new PinConnectionWrapper(webClient);
Take a look at WebClient.setScriptPreProcessor. It will give you the opportunity to modify (or in your case, stop) a given script before it is executed.
Also, if it is just the warnings getting on your nerves I would suggest changing the log level.
If you are interested in ignoring all warning log entries you can set the log level to INFO for com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument in the log4j.properties file.
LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(Level.OFF);
java.util.logging.Logger.getLogger("org.apache.commons.httpclient").setLevel(Level.OFF);
Insert this code.

Categories