Is there a way to remove HTTP response headers like Server and X-Powered-By?
My application is using a Weblogic server. I'm programming in Java using the Spring MVC framework and Hibernate, and using JSP for views.
Depends on where the headers are added. If inside your app, you can use a Spring MVC Interceptor to remove them after your controller calls. If outside your app, you might be able to try a Java EE filter configured in web.xml (the example is security, but the approach will also work for your use case). If its added after that, you may want to look at your web front end (Apache, IIS, what-have-you) to configure a filter there.
UPDATE
This answer describes an approach for removing specific headers, as the HttpServletResponse interface does not allow for header removal explicitly. You will need some trial and error to determine what portion of your stack is adding the header.
If you set concrete responseHeader to null it will be removed / not seen in response headers.
Related
I'm trying to use Spring Web on Tomcat to build an API server. This is just a request-response API, not a full web app - it won't have any web pages or static assets like images. As such, I think SpringWebMVC is the wrong technology since I don't actually want the MVC part of it, so I'm just just trying to use plain old SpringWeb.
Unfortunately, practically every tutorial I've found online uses the org.springframework.web.servlet.DispatcherServlet which is from the MVC package, not from the base package. In the base package, the only viable HttpServlet implementation I found was org.springframework.web.context.support.HttpRequestHandlerServlet. However, this servlet doesn't seem to honor #RequestMapping or #RequestBody or #ResponseBody annotations in the handler.
I thought perhaps I'd just create multiple handler servlets and just use the url-pattern on each of them in the web.xml to route them correctly, but it turns out url-pattern doesn't support path variables either (at least as far as I can tell).
So is there a way to properly set up this servlet to be able to handle request mappings with path variables like so?:
GET /foo/{fooId}
POST /foo/{fooId}/fooOperation
POST /bar/{barId}/barOperationA
POST /bar/{barId}/barOperationB
POST /bar/{barId}/barOperationC
I've been reading that the JAX-RS is built on top of servlets. Is this literally true, or it just mean that it is a higher level component? If it is, how does that work? Does JAX-RS create a servlet which parses the request and manually initializes #Path annotated classes and passes the modified parameters to them? The JSR does not seem to specify this, and none of the books that mention it go into any details.
note: I don't have trouble deploying JAX or servlets, I am just curious about the details, as it would provide a better understanding of how the web container works.
I've been reading that the JAX-RS is built on top of servlets. Is this literally true,
Simply put, YES, the JAX-RS specification is built on top of Servlets, and any other deployment method (such as mentioned by #Jilles van Gurp) is implementation specific.
Does JAX-RS create a servlet which parses the request and manually initializes #Path annotated classes and passes the modified parameters to them?
JAX-RS doesn't do anything. It's the implementation (e.g. Jersey, RESTEasy, CXF) that implements the entry point servlet. Does the implementation need to explicitly parse the request? No, not all of it. Most of that stuff is handled by the servlet container. Mainly the implementation will just need to parse the request body (as "request" implies more than just the body, e.g URL, headers).
Basically, everything related to JAX-RS is handled by the implementation. The servlet container has nothing to with anything but passing the HttpServletRequest and HttpServletResponse, just like if you were to implement your own servlet. If you were to make your own JAX-RS implementation, the servlet passing you the HttpServletRequest(Response) is the request entry point, and everything else is up you.
EDIT
as "request" implies more than just the body, e.g URL
Bad example. Actually, the JAX-RS implementation would parse the URL in order to get path parameters and query parameters. Though the Servlet container will parse the URL and add query parameters to the HttpServletRequest parameters map, that map also has form POST parameters, so the implementation will need to do it's own parsing of the query parameters also.
Jax rs does not really use or depend on servlets directly but it is commonly implemented on top of it by frameworks that implement it. In that case your application is wrapped with a servlet that delegates incoming requests to your jax rs endpoints and the whole thing is deployed in a servlet container such as tomcat or jetty.
However, for example jersey (the reference implementation) can run without a servlet wrapper in a standalone server. We use grizzly as our container for this. There is no servlet container in our application and we use the grizzly container instead. Of course the grizzly container provides a very similar execution model but you don't need a full blown application server to run it. go here for more details on grizzly
This is the official documentation of Jboss Resteasy.
RESTeasy is implemented as a ServletContextListener and a Servlet and deployed within a WAR file.
JAX-RS implementations do use ServletAPI for routing and parsing the requests. It is implementation detail and need not be mentioned in the specification.
In a bunch of the tutorials and code samples of Spring Boot and Jersey that I've seen, the following line appears:
register(RequestContextFilter.class)
What is this really used for? I don't see anything unusual in those samples, and if I remove it from my (simple) application, nothing seems to break.
RequestContextFilter's javadoc says
This filter is mainly for use with third-party servlets, e.g. the JSF
FacesServlet. Within Spring's own web support, DispatcherServlet's
processing is perfectly sufficient.
I haven't seen third party servlets in those examples.
In one of them I read
org.glassfish.jersey.server.spring.scope.RequestContextFilter, which
is a Spring filter that provides a bridge between JAX-RS and Spring
request attributes
What would be an example of a Spring request attribute?
What is some typical use case, besides needing a third party servlet?
We currently have a level 2 RESTful web service. We are updating the service to incorporate hypermedia support. We are using Spring Data Rest on the back-end to handle the setting of the HATEOAS properties. The problem we're having is that we still need to support our legacy API consumers until the migration can be completed, meaning we still need to support responses without HAL properties like "_links" and "_embedded".
For reasons that aren't really worth explaining, we cannot address this problem with URL versioning. We need instead to be able to map requests with an Accept header of "application/json" to our old controllers, and let SDR handle any requests with "application/hal+json". In essence, we'd like to use SDR as a fallback to handle API requests that are specifically requesting HAL-formatted responses.
I came across this excerpt in the SDR documentation:
We register a custom HandlerMapping instance that responds only to the
RepositoryRestController and only if a path is meant to be handled by
Spring Data REST. In order to keep paths that are meant to be handled
by your application separate from those handled by Spring Data REST,
this custom HandlerMapping inspects the URL path and checks to see if
a Repository has been exported under that name. If it has, it allows
the request to be handled by Spring Data REST. If there is no
Repository exported under that name, it returns null, which just means
"let other HandlerMapping instances try to service this request".
The Spring Data REST HandlerMapping is configured with
order=(Ordered.LOWEST_PRECEDENCE - 100) which means it will usually be
first in line when it comes time to map a URL path and your existing
application will never get a chance to service a request that is meant
for a Repository. For example, if you have a Repository exported under
the name "person", then all requests to your application that start
with "/person" will be handled by Spring Data REST and your
application will never see that request. If your Repository is
exported under a different name, however (like "people"), then
requests to "/people" will go to Spring Data REST and requests to
"/person" will be handled by your application.
This seems to imply that what we're trying to accomplish is possible, assuming the HandlerMapping order can be configured differently. I haven't been able to make that work so far though:
Setting SDR's HandlerMapping to Ordered.HIGHEST_PRECEDENCE seems to have no effect.
Setting SDR's HandlerMapping order to Ordered.LOWEST_PRECEDENCE seemed to disable ordering altogether, and my custom controllers did field the requests, but SDR was no longer responding to any requests. application/hal+json just resulted in a 406 status.
Is there any way to configure the HandlerMappings correctly such that my custom controllers take priority and SDR fields any requests not specifically mapped to my controllers?
At present I have a Spring MVC web application, which uses ServletFilter to filter each HTTP request and check whether the user has really purchased the licence by checking and validating the licence file content.
I have mapped the filter in both spring xml file as well as web.xml appropriately. As I have access to HttpServletRequest and HttpServletResponse in the filter, I am able to redirect the user to error page if the validation fails.
So, now as the title suggests is it possible to do the same thing using Spring AOP? How can Spring AOP be configured to get access to the request and response objects created by the container to redirect the user?
How can Spring AOP be configured to get access to the request and
response objects created by the container to redirect the user?
You won't be able to get the same exact behavior as servlet Filters. A Filter operates around the target Servlet by passing in the ServletRequest and ServletResponse objects. In that sense, you can get similar behavior since AOP advice can operate around the joinpoint and intercept arguments that get passed around.
However, the AOP advice can't magically have access to the request and response. It either needs to advise a method that receives them or get them from some ThreadLocal or other container. For example, Spring has RequestContextHolder which you can use to get the HttpServletRequest. But it doesn't have anything to give you the HttpServletResponse (not technically true, but it's not reliable). You could write something similar that does.
Once the advice has access to the objects, it can simply invoke HttpServletResponse#sendRedirect(..) or forward() or whatever.
The best way to implement this would be using exceptions. That way the check and the handling can be different in different situation, e.g. web application vs. normal application.
Your check could be added to particular joinpoints using aop. In case it finds something amiss, it would throw a InvalidLicenseException (extends RuntimeException). Now there are several ways in which you can redirect a request to an error page when an exception is thrown. You could add this to your web.xml :
<error-page><exception-type>InvalidLicenseException</exception-type><location>/license-error.jsp</location></error-page>
Since you're using spring, you could also use annotations. Read this
You can do it out with AOP Advises,
Advice: Advices are actions taken for a particular join point. In
terms of programming, they are methods that gets executed when a
certain join point with matching pointcut is reached in the
application. You can think of Advices as Struts2 interceptors or
Servlet Filters.
So you can configure an advice to take care of validation . you can also configure them to execute at a particular point (i.e) where it needs to be executed .
But remember scope of AOP remains only for method invocation and it doesn't provide response as servlet filters does.
Learn More ..
Simple example here to start with.