In my web-app i have front filter that is acting like router. It just routes to proper controller and action according to request url. To do that i added following in my WEB.xml
<filter>
<filter-name>FrontFilter</filter-name>
<filter-class>service.FrontFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FrontFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
But the problem is that if i want just get static html page. My filter is invoked too and starts to find controller and action. And of course it fails. I tried to place all my static content to /public folder and do in filter something like that:
if (reqURI.contains("/public/")) {
chain.doFilter(request, response);
}
but with no success.
So, how i can skip filter for static content like images and just html? I will highly appreciate your any response.
In your case to skip the filter for html file urls, Try
if (reqURI.endsWith(".html")) {
chain.doFilter(request, response);
}
My web app directory structure is
myApp
-src
- filtersPackage(all my filters lie in this package)
- servletsPackage(all my controllers and models lie in this package)
- web-content
- web
- views(all my jsp files lie in this dir)
- js(all my javascript files lie in this dir)
In login.jsp, user clicks on FB login button, inside js/FBAUth.js I collect login details and I send it to my auth.do servlet using jquery ajax POST method.
The SessionFilter allows the request to go to AuthServlet's doPost method. In AuthServlet If the credentials are correct then do the following
url = "dashboard.jsp"
request.getSession().setAttribute("uid", id);
view = request.getRequestDispatcher(url);
view.forward(request, response);
return;
I have seen in debug mode that these lines execute but my browser is still stuck on login page. The values for view.requestURI -> /myApp/web/views/dashboard.jsp and
view.servletPath -> /web/views/dashboardTmp.jsp.
I also tried response.sendRedirect(url), but still the browser is stuck on login page. Nothing executes after these lines.
In web.xml, my auth servlet is mapped as follows
<servlet>
<servlet-name>Auth</servlet-name>
<servlet-class>servletsPackage.AuthServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Auth</servlet-name>
<url-pattern>/web/views/auth.do</url-pattern>
</servlet-mapping>
I also tried calling doGet inside doPost, and executed this code in doGet, but all in vain.
What am I missing here ?
This approach seems to be a bit flawed. Your forward is not working because you are using AJAX to post data. You would need to use javascript or rather jquery to handle the redirection.
Check if your jquery AJAX function's callback method is working. print out the responseText using alert(responseText);
Check this link for more information about your problem. And check the first answer. It provides a solution for this problem.
Try to return something from your servlet (write in response writer), retrieve that as ajax response, depending upon that, do a window.location.href ="YOUR URL";
I have a JSP page (in Tomcat) which uses JSP Tags to retrieve some data. But these JSP Tags can throw exceptions (For example when parameter values are invalid). Now I want to implement a nicer error handling for these situation. I failed to find a way to GLOBALLY specify an exception handler (error-page definitions in web.xml don't work for exceptions thrown in a JSP). The only way I found so far is specifiying an errorPage attribute in the page header of ALL JSP-files.
<% page errorPage="/WEB-INF/jsp/errors/500.jsp" %>
Quite annoying to do this for ALL JSPs, but acceptable. But not acceptable is the fact that the error page is always delivered with a HTTP status code of 200. I want a 500 instead. I tried using a servlet as errorPage instead of a JSP and tried to set response.setStatus(500) and also response.sendError(500) but both calls seems to be ignored. So this code prints "200" two times and I have no idea why:
System.out.println(response.getStatus());
response.setStatus(500);
System.out.println(response.getStatus());
So the question is: How can I set the HTTP status code in JSP error handlers?
You can configure your error pages in web.xml.
<error-page>
<error-code>
500
</error-code>
<location>
/500.jsp
</location>
</error-page>
in your 500.jsp, set the directive as <%# page isErrorPage="true" %>
Instead of setStatus(500), you'd better use sendError(500) - there are some differences.
The config in web.xml works fine with sendError, however, if you don't want the config in web.xml, error-page from page directive worked just for exceptions for me, not for HTTP error codes.
I want to create a JSP page or servlet that will work in 2 ways.
A user visits their own profile page:
http//something.com/profile/
Or they visit their friends page:
http://something.com/profile/FriendsName
They could also visit their own page through an explicit URL like:
http://something.com/profile/YourName
I have a servlet-mapping setup as follows to map any requests to /profile to my JSP that will handle that request.
<servlet>
<servlet-name>Profile</servlet-name>
<jsp-file>/profile.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Profile</servlet-name>
<url-pattern>/profile</url-pattern>
</servlet-mapping>
Then I was thinking I could setup a filter that will parse the HTTPServletRequest's URL to read after the /profile/.
<filter>
<filter-name>profile-filter</filter-name>
<filter-class>ProfileFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>profile-filter</filter-name>
<url-pattern>/profile*</url-pattern>
</filter-mapping>
Now the filter could set attributes in the HttpServletRequest, how would i go about pulling those out in the JSP page to check if a user name was specified and check if your own name was set?
How would I go about creating a page scoped bean in the ServletFilter so I could use in the JSP page using jspBean like this:
<jsp:useBean id="profileInfo" scope="page" class="ProfileInfo" />
I think a filter only serves to artificially break the logic apart. You can very easily determine the value of the portion of the URL that doesn't match the url-pattern described in the web.xml. The HttpServletRequest class has a method that returns this value for you, it's called getPathInfo(). Here's an example:
<%
String path = request.getPathInfo();
if (path == null || "".equalsIgnoreCase(path)) {
// The path was empty, display the current user's profile
} else {
// Display the named profile
}
%>
This doesn't help you at all with the request beans, but I think it helps with the design.
I'm not completely following the question, but if you want a jsp to access request parameters or attributes, just do:
<%
String parameter = request.getParameter("parameter");
String attribute = request.getAttribute("attribute");
%>
You can also get access to the request url, etc... if you need to do anything with those.
Personally, I'd recommend that you use a servlet to handle your requests, and forward to the jsp of your choosing (possibly after setting session information that the jsp can use).
Using server level filters and request attributes for this kind of thing may be a bit overkill, but only you know your project's true requirements.
I have a struts-based webapp, and I would like the default "welcome" page to be an action. The only solutions I have found to this seem to be variations on making the welcome page a JSP that contains a redirect to the action. For example, in web.xml:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
and in index.jsp:
<%
response.sendRedirect("/myproject/MyAction.action");
%>
Surely there's a better way!
Personally, I'd keep the same setup you have now, but change the redirect for a forward. That avoids sending a header back to the client and having them make another request.
So, in particular, I'd replace the
<%
response.sendRedirect("/myproject/MyAction.action");
%>
in index.jsp with
<jsp:forward page="/MyAction.action" />
The other effect of this change is that the user won't see the URL in the address bar change from "http://server/myproject" to "http://server/myproject/index.jsp", as the forward happens internally on the server.
This is a pretty old thread but the topic discussed, i think, is still relevant. I use a struts tag - s:action to achieve this. I created an index.jsp in which i wrote this...
<s:action name="loadHomePage" namespace="/load" executeResult="true" />
As of the 2.4 version of the Servlet specification you are allowed to have a servlet in the welcome file list. Note that this may not be a URL (such as /myproject/MyAction.action). It must be a named servlet and you cannot pass a query string to the servlet. Your controller servlet would need to have a default action.
<servlet>
<servlet-name>MyController</servlet-name>
<servlet-class>com.example.MyControllerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyController</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>MyController</welcome-file>
</welcome-file-list>
"Surely there's a better way!"
There isn't. Servlet specifications (Java Servlet Specification 2.4, "SRV.9.10 Welcome Files" for instance) state:
The purpose of this mechanism is to allow the deployer to specify an ordered
list of partial URIs for the container to use for appending to URIs when there is a
request for a URI that corresponds to a directory entry in the WAR not mapped to
a Web component.
You can't map Struts on '/', because Struts kind of require to work with a file extension. So you're left to use an implicitely mapped component, such as a JSP or a static file. All the other solutions are just hacks. So keep your solution, it's perfectly readable and maintainable, don't bother looking further.
Something that I do is to put an empty file of the same name as your struts action and trick the container to call the struts action.
Ex. If your struts action is welcome.do, create an empty file named welcome.do. That should trick the container to call the Struts action.
It appears that a popular solution will not work in all containers... http://www.theserverside.com/discussions/thread.tss?thread_id=30190
I would create a filter and bounce all requests to root back with forward responce. Hacks with creating home.do page looks ugly to me (One more thing to remember for you and investigate for someone who will support your code).
Here two blogs with same technique:
http://technologicaloddity.com/2010/03/25/spring-welcome-file-without-redirect/
http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage
It require Servlet API >= v2.4:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
<url-pattern>/index.htm</url-pattern> <<== *1*
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.htm</welcome-file> <<== *2*
</welcome-file-list>
so you no longer need redirect.jsp in non-WEB-INF directory!!
there are this answer above but it is not clear about web app context
so
i do this:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>TilesDispatchServlet</servlet-name>
<servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TilesDispatchServlet</servlet-name>
<url-pattern>*.tiles</url-pattern>
</servlet-mapping>
And in index.jsp i just write:
<jsp:forward page="index.tiles" />
And i have index definition, named index and it all togather work fine and not depends on webapp context path.
I have configured like following. it worked perfect and no URL change also...
Create a dummy action like following in struts2.xml file. so whenever we access application like http://localhost:8080/myapp, it will forward that to dummy action and then it redirects to index.jsp / index.tiles...
<action name="">
<result type="tiles">/index.tiles</result>
</action>
w/o tiles
<action name="">
<result>/index.jsp</result>
</action>
may be we configure some action index.action in web.xml as <welcome-file>index.action</welcome-file>, and use that action to forward required page...
I am almost sure that the OP is the best solution(not sure about best practice, but it works perfectly, and actually is the solution my project leader and I prefer.)
Additionally, I find it can be combined with Spring security like this:
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<sec:authorize access="isAnonymous()">
<% response.sendRedirect("/myApp/login/login.action?error=false"); %>
</sec:authorize>
<sec:authorize access="isAuthenticated() and (hasRole('ADMIN') or hasRole('USER'))">
<% response.sendRedirect("/myApp/principal/principal.action"); %>
</sec:authorize>
<sec:authorize access="isAuthenticated() and hasRole('USER')">
<% response.sendRedirect("/myApp/user/userDetails.action"); %>
</sec:authorize>
By this, not only we have control over the first page to be the login form, but we control the flow AFTER user is login in, depending on his role. Works like a charm.
Below code can be used in struts.xml to load welcome page.
Execute some Action before loading a welcome page.
<!-- welcome page configuration -begin -->
<action name="" class="com.LoginAction">
<result name="success">login.jsp</result>
</action>
<!-- welcome page configuration -end -->
Return directly some JSP without execution of an Action.
<!-- welcome page configuration -begin -->
<action name="">
<result name="success">login.jsp</result>
</action>
<!-- welcome page configuration -end -->
No <welcome-file-list> is not needed in web.xml
Just add a filter above Strut's filter in web.xml like this:
<filter>
<filter-name>customfilter</filter-name>
<filter-class>com.example.CustomFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>customfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
And add the following code in doFilter method of that CustomFilter class
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse)servletResponse;
if (! httpResponse.isCommitted()) {
if ((httpRequest.getContextPath() + "/").equals(httpRequest.getRequestURI())) {
httpResponse.sendRedirect(httpRequest.getContextPath() + "/MyAction");
}
else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
So that Filter will redirect to the action. You dont need any JSP to be placed outside WEB-INF as well.
This works as well reducing the need of a new servlet or jsp
<welcome-file-list>
<welcome-file>/MyAction.action</welcome-file>
</welcome-file-list>
This worked fine for me, too:
<welcome-file-list>
<welcome-file>MyAction.action</welcome-file>
</welcome-file-list>
I was not able to get the default action to execute when the user enters the webapp using the root of the web app (mywebapp/). There is a bug in struts 2.3.12 that won't go to the default action or use the welcome page when you use the root url. This will be a common occurrence. Once I changed back to struts 2.1.8 it worked fine.