We have a Java EE 6 web application with JSF 2.0 running on Glassfish 3.1.
There we encountered a strange bug: the Mime type of the response header send by Glassfish to the client depends on the order of the allowed Mime types in the request header send by the Browser. So in some cases (depending on the browser), the Mime type of the response is wrong, resulting in a broken html page.
But it would take pretty long to explain that thing. So to workaround this problem we now want to do just one thing:
Force the response header type for the whole web-application to "text/html".
Currently, we do that with a Servlet Filter configured in the Web.xml:
#WebFilter("/BaseFilter")
public class BaseFilter implements Filter {
public BaseFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
configuration in web.xml:
<filter>
<filter-name>BaseFilter</filter-name>
<filter-class>com.company.web.filter.BaseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>BaseFilter</filter-name>
<url-pattern>/*</url-pattern>
<!-- these patterns should match cached resources -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
So my question is, is there a better way to enforce a specific response header, especially by just configuring it instead of implementing a ServletFilter?
Is there a Glassfish option to do that?
You can specify it in the default template by the contentType attribute of the <f:view>.
<f:view contentType="text/html">
Related
I am making simple web app project in maven spring mvc with hibernate .I have set all controllers and all work fine .Now I am gonna make restriction for users who haven't logged in .I don't wanna let them to go inside before logging in.And also After they log out ,they should be thrown out.How can I do this ?
You can use a Servlet filter. This is an object that can intercept HTTP requests targeted at your web application.
A servlet filter can intercept requests both for servlets, JSP's, HTML files or other static content, as illustrated in the diagram below.
In order to create a servlet filter you must implement the javax.servlet.Filter interface.
public class SimpleServletFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
}
public void destroy() {
}
}
When a HTTP request arrives at your web application which the filter intercepts, the filter can inspect the request URI, the request parameters and the request headers, and based on that decide if it wants to block or forward the request to the target servlet, JSP etc.
It is the doFilter() method that does the interception. Here is a sample implementation:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
String myParam = request.getParameter("myParam");
if(!"blockTheRequest".equals(myParam)){
filterChain.doFilter(request, response);
}
}
Notice how the doFilter() method checks a request parameter, myParam, to see if it equals the string "blockTheRequest". If not, the request is forwarded to the target of the request, by calling the filterChain.doFilter() method. If this method is not called, the request is not forwarded, but just blocked.
The servlet filter above just ignores the request if the request parameter myParam equals "blockTheRequest". You can also write a different response back to the browser. Just use the ServletResponse object to do so, just like you would inside a servlet.
You need to configure the servlet filter in the web.xml file of your web application, before it works. Here is how you do that:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>servlets.SimpleServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>*.simple</url-pattern>
</filter-mapping>
With this configuration all requests with URL's ending in .simple will be intercepted by the servlet filter. All others will be left untouched.
As per the security of web application x-power-by should set to empty when it displays in response header..
In our application we did this by implementing a filter.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
// App specific logic...
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("X-Powered-By","");
chain.doFilter(request, response);
httpResponse.setHeader("X-Powered-By"," ");
}
It is showing blank value in response header for x-power-by when hitting the URL, That's well and good but in our application when we hit the URL with query string appended with the URL then for the first request it shows :
x-power-by= JSF1.2
We have also commented out the below portion of x-power-by in web.xml as our application use jboss 5.0.1.
<filter>
<filter-name>CommonHeadersFilter</filter-name>
<filter-class>
org.jboss.web.tomcat.filters.ReplyHeaderFilter</filter-class>
<!--
<init-param>
<param-name>X-Powered-By</param-name>
<param-value>Servlet 2.5; JBoss-5.0/JBossWeb-2.1</param-value>
</init-param>
-->
</filter>
But doing all the two things mention above I am getting x-power-by displayed in the response header when I hit the URL with query string appended for the 1st time.
URL like:
https://example.com?html="abcd",p_ab="shdhsgdhs"
Don't know how to resolve it,any help is highly appreciated.
1) Add following entry to your application web.xml.
<context-param>
<param-name>com.sun.faces.sendPoweredByHeader</param-name>
<param-value>false</param-value>
</context-param>
2) I don't think you need any filter to overwrite this header (based on jboss documentation).
I have a gateway sevlet that forward users to many servlets that processes tasks.
each users must go first through the gateway servlet then it forwards them to the proper servlet.
I create a RequestDispatcher and execute it's forward function to the proper servlet.
the problem is that all the servlets are publicly available so they user can actually go and execute any servlets they want.
I want to allow access only to the gateway servlet and to restrict access to all others. but of course to allow the gateway to forward to the servlets.
how can it be done?
thank you!
using apache tomcat 7
Using filter to check that the current user is logged in, you'll need to write the method userIsLoggedIn() yourself, by checking session attributes:
public class LoginFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
if (userIsLoggedIn()) {
//process request normally, pass up the filter chain to the servlet:
chain.doFilter(req, res);
} else {
//go to login screen instead
RequestDispatcher dispatcher = getRequestDispatcher("login");
dispatcher.forward( request, response );
}
}
}
In you web.xml, you'll need to declare your filter:
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>
com.foo.LoginFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
To improve my java skills, I'm trying to build a simple j2ee framework (MVC).
I built it to handle every request in a FrontServlet. Here is the mapping that I used :
web.xml :
<servlet>
<servlet-name>Front</servlet-name>
<servlet-class>test.FrontServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Front</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
My problem is that when I forward the request from the FrontServlet to a JSP, obviously, the JSP request is handle by the FrontServlet and the view isn't rendered.
How can I resolve this problem by keeping the url-pattern "/*" ?
Is there a way to render a JSP in a Servlet without performance losses ?
Thanks in advance for your reply !
Solution 1 (#Bryan Kyle)
I'm trying to follow your advise. I created this filter :
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
if(!req.getRequestURL().toString().endsWith("jsp"))
{
// I changed the servlet url-pattern to "/front.controller"
req.getRequestDispatcher("/front.controller").forward(req, response);
/*chain.doFilter(req, resp);*/
}
}
<filter>
<filter-name>Filter</filter-name>
<filter-class>test.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Is it right?
Thanks !
A Filter is an inappropriate solution for a front controller approach.
You want to refine the url-pattern of your servlet so that it matches e.g. /pages/* or *.do. You don't want your front controller to kick in on irrelevant requests like CSS/JS/images/etc. To take /pages/* as an example, assuming that you've a JSP in /WEB-INF/foo.jsp, then the following in a servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response);
}
should display the JSP in question on http://localhost:8080/contextname/pages/foo.
See also:
Design patterns in Java web applications
Hidden features of JSP/Servlet
I think the problem here might be that you're using a Servlet instead of a ServletFilter.
A ServletFilter, as the name suggests filters requests by providing pre- and post-processing on the request. You'd probably want to use a Filter if you needed to do something like the following:
Provide security checks across an entire application
Set request properties that are picked up by a servlet or jsp
Compress a response
Log timing information
Etc.
Have a look at the documentation about Servlet Filters.
Seems like a stupid question to which the answer would be "Don't use encodeURL()!" but I'm working with a codebase that uses netui anchor tags in the JSPs and I need to disable the writing of JSESSIONID into the URLs as it is a security risk.
In WebLogic, you can configure this by configuring url-rewriting-enabled in weblogic.xml (I know because I wrote that feature in the WebLogic server!). However, I can't find an equivalent config option for Tomcat.
Tomcat 6 supports the disableURLRewriting attribute that can be set to true in your Context element:
http://tomcat.apache.org/tomcat-6.0-doc/config/context.html#Common_Attributes
No setting comes to mind. But this is fairly easy to do by creating a first-entry Filter listening on the url-pattern of interest (maybe /* ?) and replaces the ServletResponse by a HttpServletResponseWrapper implementation where the encodeURL() returns the very same argument unmodified back.
Kickoff example:
public void doFilter(ServletRequest request, ServletResponse response) throws ServletException, IOException {
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
public String encodeURL(String url) {
return url;
}
});
}
As found in https://fralef.me/tomcat-disable-jsessionid-in-url.html - There is a servlet spec feature to do this
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>