I'm trying to show custom error message for 404/403/500 error. I'm able to show 404/403 error but unable to show 500 error. Steps I have followed so far -
Step 1: Created a servlet which will set the status as 500
public class ErrorServlet extends SlingSafeMethodsServlet {
#Override
protected void doGet(final SlingHttpServletRequest request,
final SlingHttpServletResponse response) throws ServletException,
IOException {
try{
response.setStatus(500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step2: Crated Exception.jsp and Throwable.jsp under apps/sling/servlet/errorhandler
Step3: Added below code in both Exception.jsp and Throwable.jsp
<%#include file="/libs/foundation/global.jsp"%>
<%#taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %><%
%><sling:defineObjects /><%
response.setStatus(500);
request.getRequestDispatcher("/content/myproject/en_US/
errorpages/errorpage500.html").forward(request,response); %>
Now when I hit __http://port:host/path/to/servlet then I get "Internal Server Error" in the browser. It does not send to the expected custom error page which I mentioned.
Kindly let me know what I'm missing here.
Related
I am trying to redirect my requests to another server from filter and the following snippet is the part of redirection from filter
Filter.java
try {
String redirectUrl = “https://abc.xyz.com/home”;
response.sendRedirect(redirectUrl);
return;
} catch (Exception ex) {
logger.log(Level.INFO, "====== thus the occured exception is ====== "+ex);
}
Servlet.java
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
LOGGER.log(Level.INFO, "------ entering into download servlet !");
res.getWriter().write("Processed download request");
LOGGER.log(Level.INFO, "------ completed processing the servlet !");
return;
}
Expected : Request would get redirected from the filter and will not enter into the servlet
But what’s happening :
getting the debug logs within doGet() method
Request returns "302 Found” status code and getting redirected
Is there any way the request gets redirected from the filter itself without entering into the servlet? How tomcat forwards the request from filter to servlet?
I am currently using gwt-resty and jersey for the server side. The problem I have run into is how do I map an exception for the MethodCallback implementation. I have created an ExceptionMapper which converts the exception to json and returns it in json format but the onFailure method is giving me the generic error message for my exception, "Failed BAD Request"
The question is how do I convert the exception into something that gwt-resty can process the exception in order to get the message from the server side exception.
Here is my service implementation
service.getCurrentAddress("123456", new MethodCallback<Address>() {
#Override
public void onSuccess(Method method, Address response) {
Window.alert("Got your address" + response);
}
#Override
public void onFailure(Method method, Throwable e) {
GWT.log("failed", e);
GWT.log("Failed " + e.getMessage());
}
});
}
Here is my exception mapper.
#Provider
public class VendorExceptionMapper implements ExceptionMapper<Exception> {
#Override
public Response toResponse(Exception exception) {
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON).entity(exception).build();
}
}
I am not sure I understood your question but I think that you can parse Throwable e to get your exception in case of failure.
You can also intercept your exception by coding a restyGWT dispatcher and treat it before entering the onFailure().
I got this problem while trying to access REST web service using GWT client.
I inspect the chrome page then i got the following error from console
XMLHttpRequest cannot load http://localhost:8080/RestWeb/webresources/generic/get. Origin http://127.0.0.1:8888 is not allowed by Access-Control-Allow-Origin.
Following is my client side code
public void onModuleLoad() {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
"http://localhost:8080/RestWeb/webresources/generic/get");
builder.setCallback(new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
Window.alert("onResponseReceived");
}
#Override
public void onError(Request request, Throwable exception) {
}
});
builder.setHeader("Content-Type",
"text/plain,application/json,text/xml");
builder.setHeader("Access-Control-Allow-Methods",
"PUT, GET, POST, DELETE, OPTIONS");
builder.setHeader("Access-Control-Allow-Headers", "Content-Type");
builder.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8888");
try {
builder.send();
} catch (RequestException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My server side code is :
#Path("generic")
#WebService
public class GenericResource {
#Context
private UriInfo context;
#Context
private HttpServletResponse response;
private String content = "content";
/**
* Creates a new instance of GenericResource
*/
public GenericResource() {
}
#GET
#Path("/get")
#Produces("application/json,text/plain")
public String getXml() {
System.out.println("GET");
//response.addHeader(content, content);
return this.content + " from get method";
}
}
I tried in different ways to get answer. Please help me.
You need to change your server code to support CORS.
One option is a filter:
public class CorsFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1800");//30 min
}
filterChain.doFilter(request, response);
}
}
The web.xml needs adding the following too:
<filter>
<filter-name>cors</filter-name>
<filter-class>com.xxx.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Since it's an old question, if one is facing similar issues today - he or she may want to consider using a nice "CORS Filter" that handles all CORS stuff for you in a completely transparent way. Here's the link
I have a GWT + Spring Security web app. I was trying to add:
<security:session-management invalid-session-url="/X.html"/>
However, when I try to test this. It seems I see a:
com.google.gwt.user.client.rpc.InvocationException
with message as the HTML content of X.html. Can someone please advise on how to fix this?
Because GWT communicates with a server via Ajax RPC requests, the browser will not be redirected to X.html. What you need to do in your service calls is throw an exception if they are not authorized and handle in in void onFailure(Throwable caught) method of your AsyncCallback.
If you want to redirect to /X.html try:
Window.Location.replace(GWT.getHostPageBaseURL()+"X.html");
However, if you want to send the request to the server use RequestBuilder:
String url = GWT.getHostPageBaseURL() + "/X.html";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// invalid request
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// success
} else {
// sth went wrong
}
}
});
} catch (RequestException e) {
// couldn't connect to server
}
When my users try to do an action our website after their session has expired (for instance, if they left their browser open), the server responds with a HTTP Status 405 because the user is no longer logged in.
When this happens, I want to redirect the user to the login screen.
How can I recognize when a 405 error code is returned within GWT so I can then redirect the users?
Thanks
Edit:
Here's the filter I'm using:
public class AuthenticationFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest) {
boolean isLoggedIn = CustomSecurity.login((HttpServletRequest)req);
if (isLoggedIn) {
// TODO: How to redirect the user here???
}
}
chain.doFilter(req, res);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
web.xml content:
<filter>
<filter-name>Authentication Filter</filter-name>
<filter-class>com.company.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
How can I make that redirect the user? Also, is there a way to force the whole browser to redirect? Since this goes into a widget, I think a Window.Location.assign('url') will only redirect the widget's HTML content.
I currently work on a GWT application that does something very similar to what you are asking. However, we handle these redirects in a standard javax.servlet.Filter subclass that we define in our web.xml as per usual and it is mapped to /* so it catches all requests (we use this filter for many other reasons as well).
I don't know if you are also using a Filter or perhaps even just some sort of catch-all Servlet in your GWT app, but if you are then the solution to your issue is quite easy. You will have a handle to the HttpServletRequest and you can see if the getSession(false) method returns null then you know that the user who sent the request no longer has a session. Then you can just do a standard response.sendRedirect(...) to your login page.
For GWT-RPC you will get a StatusCodeException whenever the server returns anything but a 200 response code. The status code can be retrieved from the exception and you can redirect via GWT by using Window.Location.assign(url). For RequestBuilder the status code cqan be accessed via response.getStatusCode().
EDIT: Here is code to redirect if GWT's window isn't that root window.
private native void redirect(String url)/*-{
var win = $wnd;
while (win.parent != null && win.parent != win)
win = win.parent;
win.location = url;
}-*/;
In your RequestCallback implementation, you can check response.getStatusCode(). We have Spring Security on the backend, which is wired up to force the user to a form based login page if they are not authenticated. Upon authentication, it redirects them back.
For example:
#Override
public void onResponseReceived(Request request, Response response) {
if (SC_UNAUTHORIZED == response.getStatusCode()) {
Window.Location.reload();
}
}
use a try / catch for coders sakes!
AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
try {
throw caught;
} catch (StatusCodeException statusCodeException) {
Util.handleException(statusCodeException);
} catch (Throwable exception) {
Util.handleException(exception);
}
}
public void onSuccess(String result) {
Window.alert("Result : " + result);
}
};
then to process your results
final static public void handleException(StatusCodeException exception) {
String errorMessage = exception.toString() +
"\n CODE: " + exception.getStatusCode() +
"\n MESSAGE: " + exception.getEncodedResponse();
Window.alert("ERROR: " + errorMessage);
}
final static public void handleException(Throwable exception) {
String errorMessage = exception.toString() + "\n";
for (StackTraceElement trace : exception.getStackTrace()) {
errorMessage += trace.getClassName() + " :: " +
trace.getMethodName() + " :: " +
trace.getLineNumber() + "\n";
}
Window.alert("ERROR: " + errorMessage);
}
remember that overloading is your friend! Dont forgot that if you do not compile your code in detailed or pretty you will get garbage for the stack trace. Unless of course someone figured out how to hack the JSStackEmulation class
http://code.google.com/p/google-web-toolkit/wiki/WebModeExceptions