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?
Related
I can't update a header inside my interceptor before it gets to my controller, through the interceptor I would like to modify an already present header
public class MyInterceptor implements Filter {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse res = (HttpServletResponse) servletResponse;
//something
//myHeaders is still present when send a request
req.setAttribute("myHeaders","someValue");
chain.doFilter(req, rest);
}
}
So that inside the controller I can get the modified header:
#RestController
#RequestMapping("/")
public class FooClass{
#Autowired
private Service service;
#GetMapping("/foo")
public ResponseEntity<Void> fooApi(
#RequestHeader(value = "myHeaders") String myHeaders,
) {
service.doSomething(myHeaders);
return ResponseEntity.ok().build();
}
}
How could I do? I tried to do some research but failed.
In your Filter you can create an anonymous subclass of HttpServletRequestWrapper, override the method public String getHeader(String name) so that it returns a specific value for the header name you care about (and delegates to super.getHeader(String) if it's not the header name you care about).
Something like this:
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(servletRequest) {
#Override
public String getHeader(String name) {
if ("myHeader".equalsIgnoreCase(name)) {
return "Some value";
}
return super.getHeader(name);
}
};
chain.doFilter(requestWrapper, response);
}
I'm using spring-boot-starter-web along with embedded-jetty and starter-jersey starter. The Jersey servlet context-path is configured in application.properties to serve from /api. So all /api/.* calls are handled over to Jersey.
Since I'm using starter-web, the static content is being served from static/ directory as shown here:
All the resources listed under static/public/ can be accessed without any restrictions. But the resources under static/private should be restricted and will be shown only if logged in.
To achieve this, I've written a filter:
#Component
#Order(1)
public static class PrivateContentFilter implements Filter {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
if (request.getRequestURI().matches(".*/static/private/.*")) {
// Check for authentication in the cookie and procceed
// The cookie is handed to an auth mirco-service, that does the actual validation.
}
}
}
But this filter is only reached when the path is api/.* and not for the static content: /public/.* nor for /private.*. What am I missing here?
Everything that is under /static is the context / so your filter regex must look like this:
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
if (request.getRequestURI().matches("/private/.*")) {
System.out.println("private");
} else {
System.out.println("public");
}
filterChain.doFilter(servletRequest, servletResponse);
}
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.
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 :)
I have a problem here:
After i use a filter servlet to set session attribute, i try to retrieve the session attribute in another normal http servlet, but it looks getAttribute('system.userinfo') cannot retrieve anything. what's wrong with this? Thanks!
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpResp = (HttpServletResponse) response;
HttpSession session = httpReq.getSession();
httpReq.setCharacterEncoding("UTF-8");
UserDTO dto = new UserDTO();
session.setAttribute("system.userinfo", dto);
chain.doFilter(request, response);
}
public class FileUpload extends HttpServlet {
#SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// cannot get anything here
UserDTO userinfo = (UserDTO)request.getSession(false).getAttribute("system.userinfo");
}
}
Both servlets are in same web application.
Seems like you are not getting the session in the servlet that you think got created in the Filter. In the filter you are using req.getSession() which is always creating a new session. In the servlet you are giving request.getSession(false), the container is supposed to return null if no session exists or return an existing session. Which servlet container are you using? If you are using an IDE, can you put a debug point and compare the session IDs to confirm they are the same? Also, is your UserDTO serializable?