Serve all font files with an additional header in Spring MVC? - java

I'd like to add the following HTTP header to all responses stemming from a request for a font-file in Spring MVC:
Access-Control-Allow-Origin: *
So, I know how to set up a simple static request mapping...
<mvc:resources mapping="/fonts/**" location="/fonts/" />
But how can I add the necessary header? I know that I could implement a controller that responds to all /fonts/ requests and adds the header, but that seems like major overkill. Is there something simpler/more lightweight?

There is no need to implement a special controller for this. You can use an interceptor which extends HandlerInterceptorAdapter.
The postHandle method is passed the HttpServletResponse. You can set the header there. This interceptor can be configured to apply to requests to a specific path.
See the Spring docs here.

Related

ContentCachingRequestWrapper only captures POST request with Content-Type:application/x-www-form-urlencoded

I am trying to intercept all incoming HTTP requests and process the body attached to these requests in my Spring MVC (not Spring Boot) app. To implement this "inbound-interceptor", I am using Spring's HandlerInterceptor interface. Once the request is intercepted, I am trying to retrieve the body as follows:
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
Map<String, String[]> params = requestWrapper.getParameterMap();
byte[] body = requestWrapper.getContentAsByteArray();
Referring to this article, the limitations of trying to extract the body this way are:
Content-type of the request must be x-www-form-urlencoded
Method-type must be POST
For the application I am building, I cannot enforce either of these constraints as the calls come from heterogeneous sources beyond my control. Is there some way to override this behavior to allow extraction of the body for requests not supported by default? Or, alternatively, is there another approach to performing this task?
P.S. I am performing logging + some custom processing on the body. So solutions such as the ones mentioned in this answer are not too helpful
Have you tried Logbook? https://github.com/zalando/logbook Works with pure Spring.
Their Default Log Writer looks promising: https://github.com/zalando/logbook/blob/main/logbook-core/src/main/java/org/zalando/logbook/DefaultHttpLogWriter.java
And you may just want to extend this class to log to all Loggers you want.
You can even do something completely different with the request besides logging.

When sould I use HandlerInterceptor and ClientHttpRequestInterceptor?

I need to create a http interceptor for my spring boot app to check if the request's authorization heathers are valid, so I searched and it seems that I can use HandlerInterceptor or ClientHttpRequestInterceptor to do it.
What would be the ideal interceptor in this case? I need all requests to check this and deny access if they don't pass but to me it looks like both of the interceptors do the same thing, so what is the difference between each one?
Important detail:
I'm using #RestController to create my routes and if the route has an specific annotation (something like #IgnoreAuthentication) the interceptor won't need to check the authentication.

Filter, get url before controller (Spring MVC)

I want to write filter, and get client httprequest before controller and make some code, depends on URL.
Request can be: HttpRequest, MultipartHttpServletRequest, can be POST or GET. I need to make request to another REST API, if the URL of this request starts with api.
You should use Spring org.springframework.web.servlet.HandlerInterceptor
(hopefully this answer explain how to use it)
(or you could use an simple Servlet-Filter - see also this question Spring HandlerInterceptor vs Servlet Filters it discuss the difference between them)

Send redirect from a JAX-RS service

Is it possible to have a JAX-RS web service redirect to another web page?
Like as you would do with Servlet response.sendRedirect("http://test/test.html").
The JAX-RS web service should itself redirect. I'm using RESTEasy if that's relevant.
Yes, you can do this in Jersey or any JAX-RS implementation (including RestEasy) if your return type is a Response (or HttpServletResponse)
https://eclipse-ee4j.github.io/jersey.github.io/apidocs/1.19.1/jersey/javax/ws/rs/core/Response.html
You can use either of the following:
Response.temporaryRedirect(URI)
Response.seeOther(URI)
"Temporary Redirect" returns a 307 status code while "See Other" returns 303.
For those like me looking for 302 that fall on this answer.
By looking the code of
Response.temporaryRedirect(URI)
You can customize your response code like this :
Response.status(int).location(URI).build()
Note that status code are define in enum
Response.Status
And for example 302 is Response.Status.FOUND
Extending smcg# answer above,
You can achieve this by altering the request context in a ContainerRequestFilter by using ContainerRequestContext.setRequestUri(URI). If you see the JAX-RS specification (Section 6.2) here, there is a mention of #PreMatching request filters. According to the documentation;
A ContainerRequestFilter that is annotated with #PreMatching is executed upon
receiving a client request but before a resource method is matched. Thus, this type of filter has the ability
to modify the input to the matching algorithm (see Section 3.7.2) and, consequently, alter its outcome.
A very naive filter can be like this;
#PreMatching
class RedirectFilter: ContainerRequestFilter {
override fun filter(requestContext: ContainerRequestContext?) {
requestContext!!.setRequestUri(URI.create("<redirect_uri>"))
}
}

Custom annotations to set HTTP response headers in a JAX-RS service

I have a JAX-RS web service for which I would like to disable the same-origin policy via the new CORS HTTP headers. (I am fully aware of the security implications.)
I'd like to have a custom annotation that lets me set HTTP response headers. For example,
#ResponseHeaders({"Access-Control-Allow-Origin: *",
"Access-Control-Allow-Methods: GET"})
// Or, alternatively:
#AllowOrigins({"*"})
public String resourceMethod() { ... }
This approach minimizes boilerplate code, but I'm not sure if there's a subtle technical limitation; JAX-RS provides many annotations to handle the HTTP request but not the response, with #Produces seeming to be the sole exception.
I also prefer to stay away from too much web.xml configuration, if possible. Without explicitly needing to use a ResponseBuilder (it's OK if an annotation uses one), is there a clean way to set custom HTTP response headers?
To clarify, I'm looking for annotations that integrate with the various ways of setting HTTP response headers in order to minimize boilerplate code.
Perhaps the only spec driven approach is to use a custom MessageBodyWriter. In the writeTo() method, you are passed in a MultivaluedMap which you can set response headers on. You are also passed the annotations on the resource method invoked (so you can get whatever custom annotation you want). So read the annotations, set the headers via MultivaluedMap, and then use the OutputStream passed in to write the message body.
In Apache Wink and possibly other JAX-RS frameworks, you can create custom server side handlers that can also read the annotations on the resource method and do whatever you want (like setting response headers by default).

Categories

Resources