Servlet API - Filter Response Wrapper - java

I am new to Servlet programming and I have a question about wrapping response. Because I couldnt understand when to use it. For example I have filter and servlet as below.
Filter
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
HttpServletResponse httpServletResponse = (HttpServletResponse)resp;
httpServletResponse.getWriter().println("hi from filter");
}
Servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Hi from servlet");
}
So , What is the difference between them ? I could use both of them to write by using same response object because there are full duplex way (Sincerely, same request and response instances goes to servlet and comes to filter again) between servlet and filter , aren't there ? I am little confused. I appriciate If you could give me a decent sceneraio that could obviously demonstrate the wrapper class's goal.
Thanks & Regards :)

Related

How can we get the entity from HttpServletResponse?

The context is I want to migrate my Jersey Application to Spring MVC, For the Filter part, Jersey ContainerRequestContext has getEntity() function, which I can use to check response type is MyClientResponse or not
#Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
if (isMyClientResponse(responseContext.getEntity())) {}
but in spring Filter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
the param HttpServletResponse doesn't have such method which I can extract the entity object from it
In Java HttpServletResponse class, I only see method like
public ServletOutputStream getOutputStream() throws IOException;
but don't see method like
public Object getEntity();
Which we can get the entity body from it, so how can we get entity from HttpServletResponse? Or is there any way to convert ServletOutputStream to Object?

ClickjackingPreventionFilter in jsp: #WebFilter vs CustomFilter

So in jsp i'm trying to prevent Clickjacking,
#WebFilter(urlPatterns = "/*", initParams = #WebInitParam(name="mode", value="SAMEORIGIN"))
public class ClickjackingPreventionFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse)response;
res.addHeader("X-FRAME-OPTIONS", "SMAEORIGIN" );
chain.doFilter(request, response);
}
}
Ppl suggested to use custom filter instead of WebFilter.
https://www.baeldung.com/spring-security-custom-filter
I'm trying to understand the difference.
To my little understanding, WebFilter is a standard filter, i just need to pass parameters.
Vs custom filter is a "custom" filter as its name says.
Any comments on which way i should go ? Thx !

cant able to get proper responses in dofilter method?

I have defined servlet filter implementation in spring boot application. I could get only 200 response for all calls. How to get the appropriate response in dofilter method?
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
doFilterFunction.requestFunction(request, response, chain);
}
public void requestFunction(ServletRequest request, ServletResponse response, FilterChain chain,String x_internal_key, String session, String user, String urlPat) throws IOException, ServletException {
chain.doFilter(request, response);
}
I had removed try catch block to get the entire responses from servlet.Its working fine.

How transfer control between two Servlets with doPost methods?

I have a two servlets.
In my first servlet I use sendRedirect construction, but it call doGet from second servlet:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (someCondition()) {
resp.sendRedirect(req.getContextPath() + "/urlPattern");
} else { ... }
}
And my second servlet:
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// something to do...
}
But this is not security, user may get second servlet through compose URL. This is not permissible for my case, I need replace call sendRedirect to directly use doPost in second servlet.
Please help me replace resp.sendRedirect(...) to something calling doPost. Thank You.

how to prevent servlet from being invoked directly through browser

I was working on a web project using java servlet and jsp pages. In one of the servlet we have RequestDispatcher method and which is calling another servlet.
#WebServlet("/Demo")
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.sendRedirect("testing"); //calling other servlet
}
}
#WebServlet("/testing")
public class TestingServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("Hello World");
}
}
So, now I wanted to prevent contextRoot/testing from being invoked directly from the browser but instead only let it invoked from the other servlet(Demo)
Please suggest me if there is any way to do that.
Couple of techniques exist:
Look at writing a HTTP Request Filter. You can then inspect the incoming request and the url and reject it if the pattern matches the servlet paths that you do not want to be invoked directly.
Another mechanism is to use the security constraints in your web.xml to allow access to various paths in your application only to authorized users/roles. Look at <security-constraint> tag in web.xml
Answer given by "Romin" is correct. You have to use Filters for this. what you can do is, you can set a new session variable whenever "/Demo" url is accessed and in the filter check for the condition that session exists, if it exists allow the url or else throw error. You could do something similar like this. In "Demo" servlet
#WebServlet("/Demo")
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
HttpSession session = request.getSession() //get new session
res.sendRedirect("testing"); //calling other servlet
}
}
In Filter class add the below code
#WebFilter("/login")
public class MyFilter implements Filter{
public void init(FilterConfig arg0) throws ServletException {}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpRequest request = (HttpRequest) req;
HttpResponse respone = (HttpResponse) res;
HttpSession session = request.getSession(false) //get the existing session object
if(null != session) {
chain.doFilter(req, resp);
} else {
"redirect to some error page or home page"
}
}
public void destroy() {}
}
One approach is to check the caller's ip using ServletRequest.getRemoteAddr() and rejects it if it's not called locally
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
if(!req.getRemoteAddr().equals("127.0.0.1")) { // reject }
}
However this method wouldn't work legitimate caller (eg: proxy) is also using the same ip.

Categories