Parameters for filter, cleaner way? - filter

I'm writing a filter and want to exclude some directories from that filter.
Right now i've got this:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>filter.aFilter</filter-class>
<init-param>
<param-name>excludePatterns</param-name>
<param-value>/css,/images</param-value>
</init-param>
</filter>
I was wondering if there is a cleaner way than the comma seperated values, which I have to split in my filter. Is there a pure xml way of specifying multiple parameters in the web.xml file for your filter?
Thanks in advance

Related

Why filters and filter-mappings (same with Servlets) are defined seperately?

Does defining filter and filter-mapping seperately provide any benefit, while they could be combined in to one space? (Same is true with Servlets)
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
By combining I mean something like below.
<superfilter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<url-pattern>/*</url-pattern>
</superfilter>
It is because by separating <filter> and <filter-mapping> , you can apply the same filter to different URL patterns.
From the comment, you propose why don't just combine them into a single <filter> likes:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<url-patterns>/foo<url-pattern>
<url-patterns>/bar<url-pattern>
<url-patterns>/baz<url-pattern>
</filter>
A filter and url mapping can have more configuration properties such as <dispatcher> (or may be more in the future specification) . Suppose all of above mapping has different settings , your proposed solution may cause a
to have a large structure which look likes:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<url-patterns>
<name>/foo</name>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</url-pattern>
<url-patterns>
<name>/foo</name>
<dispatcher>ERROR</dispatcher>
</url-pattern>
<url-patterns>
<name>/foo</name>
<dispatcher>FORWARD</dispatcher>
</url-pattern>
</filter>
I think it is a matter of preference whether you like flatten or nested structure. I guess that Servlet Spec designer like flatten more and so go for the flatten choice.

SonarQube Critical Violation asks for filter on rest api web.xml file

The SonarQube hint (rule "Web applications should use validation filters") suggests this compliant solution:
public class ValidatingHttpRequest extends HttpServletRequestWrapper {
// ...
}
public class ValidationFilter implements javax.servlet.Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
chain.doFilter(new ValidatingHttpRequest( (HttpServletRequest)request ), response);
}
}
and in web.xml:
<filter>
<filter-name>ValidationFilter</filter-name>
<filter-class>com.myco.servlet.ValidationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
But I have no clue of what validations are expected here. My code is a rest api (resteasy implementation) and all services are under "/rest/* path. Is this a false positive case?
According to the OWASP, injection flaws are one of the top application security risks (link). The basic prevention idea includes automatic validation of all input values using the whitelist approach. In order to implement it in Java EE, OWASP suggests using a custom filter, you can find more details with some restrictive patterns here.
tl;dr: Sonar requires you to filter out some potentially unsafe input characters.
In my opinion, this rule is too general and does not apply to all of the possible applications - it is possible to prevent code injection in many ways.

web.xml init params more than one param-value

I would like to ask if it is possible to add more than one param-value in
<param-value>
tag?
For example:
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext, org.springframework.web.context.support.XmlWebApplicationContext</param-value>
</init-param>
Thank you!
That depends on the parameter. The code which reads the value can parse it in any way they like. This means there is no way for you to say "I want to pass multiple values" and no standard.
Spring doesn't support more than one class as contextClass. This class is used to build the application context and a Java class can always only have a single concrete type. If you don't specify the parameter, Spring will use XmlWebApplicationContext as default. If you use annotated Java config, then you will want to replace this with org.springframework.web.context.support.AnnotationConfigWebApplicationContext.
The classes which configure Spring need to specified with contextConfigLocation which takes a list (comma and/or space separated) of file or class names.
For details, see the documentation: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-java-instantiating-container-web and http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
What you done is correct , it should be separated by comma , as the delimeter
<context-param>
<param-name>contextClass</param-name>
<param-value>ex1.com,ex2.com,.....</param-value>
</context-param>
or you can put them like below to make it more readable,
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
org.springframework.web.context.support.XmlWebApplicationContext
</param-value>
</context-param>
should work as expected
you can use several values in <param-value>, but only if method can accept array of values.
example 1:
<init-param>
<param-name>suffixExclusions</param-name>
<param-value>.jsp, .ftl</param-value>
</init-param>
it works fine, because there can be many parameters.
example 2:
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true, false</param-value>
</init-param>
will be an exception:
org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'forceEncoding'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [true, false]
[INFO] [talledLocalContainer] at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:480)
[INFO] [talledLocalContainer] at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:512)
[INFO] [talledLocalContainer] at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1120)
cause method expect only one boolean value.
UPD
according documentation expected only one class in parameter contextClass

How to use context-param defined in web.xml in dispatcher servlet?

I have a very small concern, to which I couldn't find an answer even after Googling for quite sometime.
How do we use context-param defined in web.xml in the dispatcher servlet?
In my web.xml, I have defined it like this:
<context-param>
<param-name>root.path</param-name>
<param-value>/root</param-value>
</context-param>
I can access it in my Java class using the below lines of code:
String rootPath = sce.getServletContext().getInitParameter("root.path");
However, I don't see a way to use this value in dispatcher servlet. I want to use a variable for /root in the below case than the value itself.
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="file:/root/main.properties" />
Any help is highly appreciated.
Thank you.
Try using
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="file:/#{contextParameters.root.path}/main.properties" />
This will create problem if we give name as "root.path", instead give name as "root_path"

Spring form:select does not render with an option "selected" attribute

I'm stuck in a problem with converters and bindings.
I have a page with a form:select where I bind an list of object with itemValue
<form:select id="id_a" items="${items}" path="builder" itemValue="id" />
I've created 2 converter that convert this bean. One convert from the bean to a string displaying the description the other convert from an id to obtain the bean from the DB.
private Converter<BuilderType, String> getBuilderTypeToStringConverter(){
return new Converter<BuilderType, String>(){
public String convert(BuilderType builder){
return builder.getDescription();
}
};
}
private Converter<String,BuilderType> getStringToBuilderTypeConverter(){
return new Converter<String, BuilderType>(){
public BuilderType convert(String id){
return builderService.findById(new Long(id));
}
};
}
So when I create the bean everything works fine, I see the description in the select field and when submit the form the id gets transformed to to the real bean and put into the model attribute before reaching the controller.
the problems is when I try to update, my select is still correctly populated, but the actual value is not selected. There is no option with the attribute "selected" to initialize correctly the select.
That's really strange because I have an sample application (petclinic) of spring roo that actually with the same type of converters populate correctly the select.
The only way I found to get this working is a bit is to add ".id" to the path :
<form:select id="id_a" items="${items}" path="builder.id" itemValue="id" />
But this way on submit I receive back in the controller a empty "builder" with only the id set, not the comprete object I normaly receive when the correct converter gets invoked.
I really have no idea what could be the difference between the two applications that makes one work and not the other... even the spring library version are the same!
I've found the problem. It seems that in the web.xml of working application there was another filter I was not using, just adding this made everything work fine:
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
It's really strange because nowhere I've found that this was mandatory or even have little a connection with the spring tags to make them work as expected!
I think you should define equals method for the entity class (BuilderType) and compare the instances by id. Otherwise, form generation is not able to find the current value from the list of items for options.
You can verify this by checking calls to equals when implemented in BuilderType.
I was facing the same problem and was able to solve it with help of this comment and the sample code (AbstractEntity.java) in Spring Data book.

Resources