Could you help to check why doFilter not getting called
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<filter>
<filter-name>roseFilter</filter-name>
<filter-class>net.paoding.rose.RoseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>roseFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
</web-app>
class signature:
import org.springframework.web.filter.GenericFilterBean;
public class RoseFilter extends GenericFilterBean {
404 is returned while call http://localhost:8080/hello/world, I set the breakpoints at
doFilter, it seems doFilter not called?(I tried tomcat 6.0.18, 6.0.29, jdk1.6)
The filter won't be invoked when:
The filter class is missing in the classpath and/or is not loadable or instantiable. You should however have noticed it in the server's startup logs. Solution is to be found based on the interpretation of the exceptions/errors found in the server logs.
There's another filter running before in the chain which isn't calling FilterChain#doFilter(), but rather RequestDispatcher#forward() or include() which caused the subsequent filters in the chain being completely skipped (when they do not listen on FORWARD or INCLUDE dispatchers; they by default only listens on REQUEST dispatcher). Solution is either to fix the wrong filter, or to add <dispatcher>FORWARD</dispatcher> etc accordingly, or to rearrange the filter declarations in web.xml so that your new filter comes before the another filter (you in turn only need to ensure that your new filter is using the FilterChain#doFilter() properly :) ).
The request URL is plain wrong. You used http://localhost:8080/hello/world. With a filter listening on /*, this means that the webapp context should be ROOT or at least /hello. Verify your webapp context. I'd just retry with an URL which points to a valid JSP/Servlet inside the same webapp which generates a non-404 response. Does the filter then get called as well?
What's the web request look like? Can you try changing your url-pattern to *.jsp instead of / * ? If you are using something other than pure JSP then change it to whatever the request ending extension is (like for struts it is usually *.do).
Related
In tomcat for a certain url, I want to skip all the filters and execute a servlet and I thought placing the servlet before the filter will to as I expected but still the filters behind the servlet mappings are executing. Am I doing anything wrong?
For instance, this is my web.xml
<servlet>
<servlet-name>APIRedirection</servlet-name>
<servlet-class>com.test.APIRedirection</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>APIRedirection</servlet-name>
<url-pattern>/abc/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>filter</filter-name>
<filter-class>com.test.filter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
So when the incoming url contains "/abc/" I want my servlet to execute and skip the filters. I placed my servlet before all the filters but still the filters are getting executed when the incoming url contains '/abc/'.
There is no concept of servlet before filter.
If servlets url mapping qualify filters url mapping then filter is executed before servlet.
I got your requirement you just don't want to hit Filters for certain urls.
a. If your application is still in starting phase, you can configure as given below
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/filtered/servlet1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/filtered/servlet2</url-pattern>
</servlet-mapping>
...
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/filtered/*</url-pattern>
</filter-mapping>
And the servlet url for which you want to bypass filter
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/unfiltered/servlet1</url-pattern>
</servlet-mapping>
2. If your application is already developed, and you configured a filter already with mapping /* then you can not skip that filter being executed. But you can add one more filter before that filter. Here filter order plays an important role,(reference for filter order) you can perform same functionality which you expected from a servlet. In your filter you just have to break filter chain and send response as given below
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException
{
//your business logic
// construct responseToSend
response.getOutputStream().write(responseToSend);
return;
}
For more information of breaking filter chain refer this question
I coming back to Spring after spending 5 years doing other things. I have an initial projects which is designed to provide a HTTP REST service that returns JSON.
My problem is that I cannot get the service to convert the response to JSON. Instead I get errors like this:
javax.servlet.ServletException: Circular view path [hello]: would dispatch back to the current handler URL [/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:205) ~[spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:145) ~[spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) ~[spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
...
My web.xml looks like this:
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>au.com.abc.service</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>fxServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>au.com.abc.controller</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>fxServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
And my Controller class looks like this:
#RestController
public class FXRESTController {
#RequestMapping(value = "/hello")
public Map<String,Object> rootContextHandler() {
Map<String,Object> data = new HashMap<>();
data.put("X", "abc");
return data;
}
}
It really cannot get any simpler. I've been passing the request header Accept='application/json', but it's still not working. I have had this type of thing working in the past, but I don't have that code anymore. I can also see this in the logs:
... Invoking request handler method: public java.util.Map au.com.abc.controller.FXRESTController.rootContextHandler()
... Service responding
... Invoking afterPropertiesSet() on bean with name 'hello'
... Rendering view [org.springframework.web.servlet.view.JstlView: name 'hello'; URL [hello]] in DispatcherServlet with name 'fxServlet'
... Added model object 'X' of type [java.lang.String] to request in view with name 'hello'
... Error rendering view [org.springframework.web.servlet.view.JstlView: name 'hello'; URL [hello]] in DispatcherServlet with name 'fxServlet'
Which suggests to me that it's trying to render a JSTL view. Why - I don't know considering I've asked for JSON.
Any ideas what I've done wrong?
I've read a ton of blogs and so far I cannot see any differences between what they have done and what I've done.
Oh and here are my gradle resolved dependencies:
You only have a controller, that doesn't do anything for enabling JSON.
You have to have a #Configuration annotated class which is also annotated with #EnableWebMvc to have automatic JSON conversion enabled. See also this section of the reference guide.
#Configuration
#EnableWebMvc
public class WebConfiguration {}
You are running with the DispatcherServlet defaults which are very basic.
Use #ResponseBody.
ALso donot direct all request to spring
<servlet-mapping>
<servlet-name>fxServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ALways better to add a layer like this:
<servlet-mapping>
<servlet-name>fxServlet</servlet-name>
<url-pattern>/webapp/*</url-pattern>
</servlet-mapping>
FOr a given project only following request will be directed to spring
http://localhost:8080/Proj/app/hello
Other request can be handled different..thus you can handle request in a different way and not dependent on spring..like
http://localhost:8080/Proj/servlethandler
The above request will not go to spring and can be intercepted by a servlet etc..
I Have REST service
#Path("/rest")
#Component
public class MyRestService
{
#Inject
private MyBean bean;
#GET
#Path("/do")
public String start()
{
this.logger.info("Before do " + Thread.currentThread().getId());
String result = this.bean.do();
this.logger.info("After do " + Thread.currentThread().getId());
return result;
}
}
which calls method of injected Spring singleton bean (with some state inside)
#Service
public class MyBean
{
public String do()
{
// do something big...
}
}
When I call ".../rest/do" in browser the first call goes as expected, but if I make same call in another tab this call waits until first is finished to process second call in same thread.
If I do second call as ".../rest/do?async=true" it does not wait and processes second request in new thread, but if I do both requests as ".../rest/do?async=true" - second one again waits for the first one to finish.
What could be the reason for such behavior? Is it actually expected?
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<display-name>My REst</display-name>
<!-- spring configuration by annotations -->
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<!-- spring configuration class -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>app.Config</param-value>
</context-param>
<!-- to return data according to extension -->
<context-param>
<param-name>resteasy.media.type.mappings</param-name>
<param-value>json : application/json, xml : application/xml</param-value>
</context-param>
<!-- this has to match with resteasy-servlet url-pattern -->
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<!-- resteasy spring connector (to use DI in rest-resources) -->
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<!-- this has to match with resteasy-servlet url-pattern -->
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- Bind Jboss's TransactionManager (EntityManagerFactory) to JNDI -->
<persistence-unit-ref>
<persistence-unit-ref-name>persistence/ReferenceDataDS</persistence-unit-ref-name>
<persistence-unit-name>ReferenceDataDS</persistence-unit-name>
</persistence-unit-ref>
</web-app>
You can solve this issue running your application server in debug mode. Do the test with two different clients e.g. Firefox, Chrome, IE, Opera, ... While waiting for the answer pause all the threads.
If you see only one workerthread active, then the settings of the application server are the problem.
If you see multiple workerthreads active but one of them is waiting for a semaphore, you have a problem with multiple threads accessing the same resource
If you have multiple workerthreads active but one of them is waiting for a connection to the persistence store, then you're datasource doesn't have a connection pool.
Since i just spent a whole day to fight this exact problem (without realizing that a changed parameter would have lead to parallel execution):
The culprit is the browser.
In Chrome, the calls get queued when you call the same resource from two tabs, but executed in parallel when you make the calls from different windows.
In IE11, they always get executed in parallel
In Firefox, it doesn't matter whether the calls are from different tabs or windows, they always get queued.
All of them execute them in parallel when the URLs are slightly different, by adding a different fragment or parameter.
OK so I've previously used this technique with classic web.xml, but am having trouble getting it to work now that I'm using the WebApplicationInitializer.
My WebApplicationInitializer includes this code:
HttpConstraintElement constraint = new HttpConstraintElement(
TransportGuarantee.NONE,
new String[]{"sponsorUsers"});
ServletSecurityElement servletSecurity =
new ServletSecurityElement(constraint);
dispatcher.setServletSecurity(servletSecurity);
I'm trying to require basic auth (username+password) for any http methods for any resource request within the servlet.
All I get back is a 403 - no prompt for the username.
My suspicion is that I need to set the auth-method to BASIC, as I would in xml:
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>User Auth</realm-name>
</login-config>
But don't see the equivalent in the Java classes. Any help? Thanks!
A WebApplicationInitializer is basically the Spring extension of Servlet 3.0 ServletContainerInitializer.
There are a few things you cannot do with ServletContainerInitializer, or ServletContext to be more specific, and one of them is to configure some security components, ex login-config.
Instead you can have both a ServletContainerInitializer and a web.xml using the attribute metadata-complete set to false. For example,
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="false" version="3.0">
In which you then add your <login-config> element.
I wrote a filter to decide user landing page before it reach my welcome-file. The welcome-file is written in such a way that it takes input from the filter and navigate the user to a specific page.
My welcome-file tag is...
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
and my filter configuration is
<filter>
<filter-name>LandingPageFilter</filter-name>
<filter-class>com.mypack.test.filters.LandingPageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LandingPageFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The above format is working good whilst every request is passing through this filter, which I want to avoid. When I hit http://localhost:8000/landing it should reach the filter for the first time only and later even if I access http://localhost:8000/landing/edit it should actually execute the relevant servlet bypassing the filter.
I tried this as well <url-pattern>/*/index.jsp</url-pattern> but no use. Why I use this because the context may vary but the app would be same.
Use
<url-pattern>/index.jsp</url-pattern>
instead of
<url-pattern>/*/index.jsp</url-pattern>
So your filter mapping part will become like this
<filter-mapping>
<filter-name>LandingPageFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
Irrespective of the context this works because / represents the path after the context path.
For example if you have two context paths say a and b with two deployments of same application in your server and you are accessing them using the URLs
http://localhost:8000/a/
and
http://localhost:8000/b/
then / in the url-pattern represents / after context roots a and b. So your filter will be executed only for index.jsp.