GWT 2.5.0 DevMode
I had a simple test on file upload below,
startupUrl: http://127.0.0.1:8888/UploadTest.html?gwt.codesvr=127.0.0.1:9997
<g:FormPanel ui:field="fpUpload">
<g:VerticalPanel>
<g:FileUpload name="fileData" ui:field="fuUpload" />
<g:Button ui:field="btUpload">Upload</g:Button>
</g:VerticalPanel>
</g:FormPanel>
#UiHandler("btUpload")
public void onClickUploadButton(ClickEvent e) {
System.out.println("fileName:" + fuUpload.getFilename());
fpUpload.setEncoding(FormPanel.ENCODING_MULTIPART);
fpUpload.setMethod(FormPanel.METHOD_POST);
fpUpload.setAction("/files");
fpUpload.submit();
System.out.println("Submitted, please wait!");
}
#UiHandler("fpUpload")
public void onSubmitComplete(SubmitCompleteEvent event) {
System.out.println("Submit completed!");
}
Output:
fileName:C:\fakepath\one_file_chosen_to_upload
Submitted, please wait!
However, the server didn't receive the submit request, so "Submit completed!" never appeared.
Meanwhile, the traffic was snooped below, the submit request didn't send out at all.
$ tcpdump -A -i lo port 8888
No exceptions were thrown, too. Any idea?
#EDIT
The problem is reproducible on ProdMode.
#EDIT 2
After merely rebooting the machine, now the problem seems gone just as silently as the http submit request was ignored to emit over the wire. Unfortunately, i have no clues why.
It seems you have not coded an appropriate servlet to handle the multipart request, also you have to configure that servlet in your web.xml. Could you add to your question your servlet code and the content of your web.xml ?
Note that onSubmitComplete is not executed if the server return a 404. Try to inspect the server response with Firebug, or change the form action by any thing so as you get the same failure.
FYI, there is a ibrary: gwtupload which is very easy to use and is plenty of nice features, maybe you could take a look to theirs example page and give a try.
Related
So I have a Sling servlet that reads data from another API (let's call it APIX) and APIX gives me the data in JSON format.
When I debugged my code, it seems the response I get from APIX is intact.
When I pass the JSON I got from APIX to browser, I can see that AEM has "link checked" all the links I have in the JSON. I don't want AEM to do anything with my data.
Base on this Adobe page, I added these lines in my code:
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
LinkCheckerSettings linkCheckerSettings = LinkCheckerSettings.fromRequest(request);
linkCheckerSettings.setIgnoreExternals(true);
//body of the code here
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
printWriter.write(jsonResponse);
linkCheckerSettings.setIgnoreExternals(false);
}
No effect. I can still see these string
<img src="/libs/cq/linkchecker/resources/linkcheck_o.gif" alt="invalid link: _blank\\" title="invalid link: _blank\\" border="0">
everywhere.
I then tried disabling Linkchecker (via configMgr/Day CQ Link Checker Transformer) and still no effect.
How can I do it?
I called the Slng servlet by typing this URL in my browser: http://localhost:4502/servlets/getpublications?name=john.smith
Thanks!
EDIT:
This is a sample of the JSON data I'm getting from APIX (debugging on IntelliJ):
"LINKS":[
"<a x-cq-linkchecker=\"skip\" target=\"_blank\" href=\"http:\/\/www.google23.com\">[Web Link]<\/a>"
]
This is what I'm getting on the browser (the a tag was somehow replaced by an img tag)
"LINKS":[
"<img src="/libs/cq/linkchecker/resources/linkcheck_o.gif" alt="invalid link: _blank\\" title="invalid link:_blank\\" border="0"> [Web Link]<\/a>"
]
I have tried using valid and skip for x-cq-linkchecker but nothing happens.
Day CQ Link Checker Transformer config screenshot
I don't think disabling LinkChecker at a global level is recommended. There are a few more ways you can achieve this and place the restriction to only certain use cases -
If the link contains special prefixes like tel:, mailto: etc, - you'll have to add them to Day CQ Link Checker Service in /system/console/configMgr to disable LinkChecker for these links.
Add this parameter x-cq-linkchecker="valid" to the <img> tag to ensure links are marked as valid in AEM - even though AEM considers them invalid.
You can also use x-cq-linkchecker="skip" to skip link checker validation for this element.
You might encounter caching issues after updating the above params(2. and 3.), just try deleting contents in /var/linkchecker before you start testing.
There are multiple techniques for handling special url patterns, Refer here. And a very good link checker guide here.
Technique 1: Code way(Not recommended since not maintainable). Add class x-cq-linkchecker=”skip”
Technique 2: Disable link checker. Definitely not recommended in author. Author should witness broken links visible. However it is recommended to disable in publish rather than showing ugly broken link icon.
Technique 3: Add special url pattern. Your link checker should looks like this:
In a plain Play application I have the following scenario.
A route file which looks like this:
GET /accounts/add controllers.Accounts.add()
POST /accounts controllers.Accounts.create()
The first route results in a view where I can add a new account. The form to submit the new account looks something like this:
#helper.form(action = routes.Accounts.create()) {...}
Now the controller binds the input to the form and checks for any validation errors:
public static Result create() {
Form<Account> form = Form.form(Account.class).bindFromRequest();
if (form.hasErrors()) {
return badRequest(views.html.account.add.render(form));
}
...
}
Now the thing is, the client will see the same view with some additional error messages. However, meanwhile the URL has changed from http://example.com/accounts/add to http://example.com/accounts.
If the client now reloads the browser this calls GET http://example.com/accounts (which isn't even mapped in this scenario - thus getting a 404 - Not Found).
Maybe it's just me but I find this kind of annoying and browsing some GitHub projects I couldn't find a good solution for this case.
Of cause things would be much simpler if the second route is rewritten to:
POST /accounts/add controllers.Accounts.create()
... in which case everything works fine. But from a REST point of view this doesn't feel good either. The same applies to update scenarios (having GET /accounts/:id/update vs. PUT /accounts/:id).
Is there a guide on how to handle this? Am I getting something wrong or is this no problem at all (from a pragmatic point of view)?
It's not possible to leave the previous URL because a request for a new address has already been made. A controller only provides response for a requested resource. To go to the previous URL you could only make a redirect in case of validation failure but you would lost errors that way so this is not a solution.
I suggest mapping both actions with the same URL. This way you would solve problem with the browser reload.
If you create a REST service for http clients that aren't browsers you will probably want to serve different response than a simple http page. The separation of actions for particular clients could be a good solution for keeping REST API clean and a browser user happy.
I just started to learn Grails and my question of this could be dumb. So apologies if it is dumb. I have a client program and a REST web service - both coded by me. The client program calls the RESTful service using POST (to add record to a database). When I call object.save() there are some validation errors that are returned.
In my gsp I have fieldError tag coded to read the error message for each field in the bean and show it in the screen. I'm assuming I needed to pass the domain instance that failed the validation from RESTful service to the client so the client could inturn send it to gsp which will automatically show errors. Correct me if this is wrong. however I don't know how to pass the domain instance object as XML from the web service. When the validations are successful though, I get the object like "render object as XML". However when validations fail, I don't know how to pass the entire failed domain instance object back as xml.
I tried to code,
if (student.save()){
render student as XML
} else {
student.errors.each(){
println it
}
def errmsg = student.errors.allErrors.collect { g.message(error:it) }
render(contentType:"text/xml") {
respstud {
for(err in errmsg) {
message(err)
}
}
}
}
This returned the specific error message back to the client as xml, but I'm needing the entire student object to be sent back to the client when save() fails also. Can someone please help?
let me know if you need more info. This is my first post in stackoverflow so I don't really know if I have to provide more details. Any help is greatly appreciated.
Thanks,
Prem
Because the request is being made via ajax, you will need to handle it the Ajax way.
Your gsp is compiled on the server and sent as html to the client when the page is first requested.
One way to handle this would be to set an error on the ajax response and return a snippet of the code you would like to render.
The response may then be handled in the error section of your calling JavaScript and the code snippet rendered on the page where you wish.
I have Restful API that responds 404 errors when an item is not found, but have different messages depending on the reason why the item is not found (unknown, not available, ...), it is done this way using Spring MVC :
response.sendError(HttpServletResponse.SC_NOT_FOUND, "NOT_AVAILABLE");
(this works fine with any browser, displaying 404 errors with "NOT_AVAILABLE" as message)
Now, I'd like to get that message back into my Java code using Spring RestTemplate in order to manage them.
I tried this:
try {
rest.put(apiRootUrl + "/item/{itemId}", null, itemId);
} catch (HttpClientErrorException e) {
if (NOT_FOUND == e.getStatusCode()) {
switch (MyErrorCode.valueOf(e.getStatusText())) {
case NOT_AVAILABLE:
return displayNotAvailableError();
case UNKNOWN:
return displayUnknownError();
default:
// ...
}
}
}
but in the getStatusText(), I always got the NOT FOUND label (from 404) and not my custom value.
Does someone know if it is possible to retrieve the custom message from 404 errors? And therefore how?
thanks a lot!
Edit: I run on a Tomcat server (which sends the 404 HTML page) and this does not append with a Weblogic server
OK, after digging a bit more, the solution is in fact very simple !
Tomcat was sending back to me its default 404 page, I just needed to tell it to use mine!
How to do this:
create a 404.jsp page like this:
<%# page pageEncoding="UTF-8" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:out value="${requestScope['javax.servlet.error.message']}"/>
reference it in your web.xml
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
And now, you can get the message in your client using e.getStatusText()
I am using symfony 1.4.
I need to redirect certain urls when 404 error occurs.
Let's say user is looking for a url http://example.com/oldurl and it doesn't exist I want to check if this url is set for redirect.
If url is set to be redirected I would like to redirect it to that url.
QUESTION: Which event should I hook into to get info about the requested url, that got redirected to 404 error page ?
P.S We only want to check for redirection if page doesn't exist. We do not want to run "the check" for every request, only when page not found!
thanks a lot!
Symfony fire an event each time a page is not found: controller.page_not_found.
You can find it in the documentation: http://www.symfony-project.org/reference/1_4/en/15-Events#chapter_15_sub_controller_page_not_found
Edit:
You can retrieve the url in the method that listen to this event by calling the context. With something like that:
$context = sfContext::hasInstance() ? sfContext::getInstance() : null;
if(null !== $context)
{
$requested_url = $context->getRequest()->getUri();
}
You can give a closer look to the plugin sfErrorNotifierPlugin, it catches exception and 404 error and send an email for a report. Look at how they handle 404 error.
I don't know where to hook exactly inside the execution stack, but I know the general cleaner way through routing. If you are doing routing without still having in code the default routing rule (which you shouldn't by practice since), then it would be as simple as the following in your app routing.yml (at the end):
catch_all:
url: /*
param: { module: yourModule, action: handleNotFound }