Does Spring Boot Support Multiple Content Negotiation Strategies Base On URL Pattern - spring

Our Spring Boot webapp consists of a couple of URL strategies. The /api URL's are for REST services and content negotiation is consistent with best practices (headers or request parameters). The /web URLS are for a legacy Freemarker application which uses URL extensions for mapping content type (.html, .json, etc). A recent change by Spring has caused the problem (https://github.com/spring-projects/spring-framework/issues/24179).
The content negotiation for the two URL's are different and I was wondering if we could define multiple content negotiation strategies...using URL's to select between them.

Yes, content negotiation is possible in the Spring Boot application as you can use Request parameter or header values to return different content-type based on your requirement for example. You can use the same URL pattern and use content-type request parameter to get the desired type and return the content like .html or.json but make sure you are adding marking as #RequestMapping(value = "sign_in", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_HTML_VALUE})

Related

SpringCloud Gateway redirect based on URL and Method

Springboot : 2.0.4.RELEASE
I am using Swagger documentation to create RouteDefincationLocator to redirect my incoming request to appropriate service in Spring.
Now there are some services who has same URL with different http method name. i.e
POST /v1/orders (This is more restricted then other url)
GET /v1/orders?view=single
Now in Spring cloud gateway I want to apply 2 different set of filter on each URL
i.e.
For : POST /v1/orders
Filters
ValidUser
Has Create Permission
For : GET /v1/orders?view=single
Filters
ValidUser
I have implemented RouteDefinitionLocator, and implemented method
public Flux<RouteDefinition> getRouteDefinitions()
I have also set predicates PredicateDefinition but this is only verifying URL Path and not method
There are lots of consumer of these services, so I can not change the URL
Can someone tell me how can I add different filters based on incomming URL+Method
Thanks in advance.

Path variable in servlet url for Spring web mvc

I'm wondering is it possible to have path variable in server.servlet-path with DispatcherServlet? I know of course it possible in controller, but I'd like to have it in one place instead of updating 70 endpoints.
Like:
server.servlet-path=/{client-name}/api/v4
And for example that client-name will be available in request attributes, headers, etc.
Or I need to implement my own dispatcher which will do that logic?

spring boot: separate REST from static content

I'm using spring-boot-starter-data-rest and spring-boot-starter-web.
I've made a simple project using a CrudRepository, letting spring boot generate the rest request mappings.
Now, I want to add a client -- making the rest calls -- live under ./.
Hence, I'm trying to prefix the paths for the rest calls (and only those!) with /api.
I've tried the answers from :
How to specify prefix for all controllers in Spring Boot?
using settings in the application.properties file
server.contextPath=/api/*
spring.data.rest.basePath=/api/*.
But still the static content (e.g. index.html, *.js, *.css) is not fetched using ./. There urls are also prefixed by "/api/".
The rest calls are properly served under /api/foos.
Is there a way to tell spring not to treat urls that lead to sources located in src/main/resources/public as 'rest-controllers'?
Update
Setting the property
spring.data.rest.basePath=/api/*
works perfectly. (I still had a programmatic bean configuration in my sandbox overriding this setting).
Spring controllers are made for serving both HTML and JSON/XML. The first one is done via Spring MVC Views and some template engine like Thymeleaf, the latter is handled entirely by Spring and #RestController.
There's no way to have a context path for only the controllers that returns JSON or XML data, and not for the other controllers as well, this also goes for static content. What you typically do is have some static variable containing the prefix you want for your APIs, and the use that in the controller's #RequestMapping. i.e.
#RestController
#RequestMapping(MyConstants.API_LATEST + "/bookings")
public class MyBookingsController {
...
}
You probably want to approach the prefix problem with something along these lines anyway. It is common to have to support older API versions when you have breaking changes, at least for some time.

Spring MVC insert URL to another endpoint in the view

I'm migrating a Play! 1.2 web application and moving to Spring Boot + Spring MVC. Some views contain URLs to other endpoints. For example, I display the book title on the page and next to it I want to add the URL to go the book's details page (e.g. localhost/books/{id}).
In Play! 1.2 the controllers are static, and there is also a Router which can create the full URL for a method belonging to another controller (Router.getFullUrl("BookController.bookDetails", args)), but how do I achieve this with Spring MVC?
Best regards,
Cristian.
If you are trying to get the app/deployed name automatically in .jsp files to make the urls, then please make use of context path. An example below :
<c:set var="context" value="${pageContext.request.contextPath}" />
<script src="${context}/themes/js/jquery.js"></script>
From your requirement "admin.myapp.com","admin-test.myapp.com" are server names right? Something like http://admin.myapp.com/book/{bookId},http://admin-test.myapp.com/book/{bookId}. In Spring app, relative path in jsp can be accessed using pageContext.request.contextPath
I also found the UriComponentsBuilder and ServletUriComponentsBuilder. They are similar to the Play! Framework router and provide methods for building URI's, handling parameters and the query etc. We chose to annotate the controllers' methods using constants and then use the same constants with the UriComponentsBuilder to build back the path and create the request query for GET requests.

Spring MVC 3.0 - restrict what gets routed through the dispatcher servlet

I want to use Spring MVC 3.0 to build interfaces for AJAX transactions. I want the results to be returned as JSON, but I don't necessarily want the web pages to be built with JSP. I only want requests to the controllers to be intercepted/routed through the DispatcherServlet and the rest of the project to continue to function like a regular Java webapp without Spring integration.
My thought was to define the servlet-mapping url pattern in web.xml as being something like "/controller/*", then have the class level #RequestMapping in my controller to be something like #RequestMapping("/controller/colors"), and finally at the method level, have #RequestMapping(value = "/controller/colors/{name}", method = RequestMethod.GET).
Only problem is, I'm not sure if I need to keep adding "/controller" in all of the RequestMappings and no matter what combo I try, I keep getting 404 requested resource not available errors.
The ultimate goal here is for me to be able to type in a web browser "http://localhost:8080/myproject/controller/colors/red" and get back the RGB value as a JSON string.
You are not correct about needing to add the entire path everywhere, the paths are cumulative-
If you have a servlet mapping of /controller/* for the Spring's DispatcherServlet, then any call to /controller/* will be handled now by the DispatcherServlet, you just have to take care of rest of the path info in your #RequestMapping, so your controller can be
#Controller
#RequestMapping("/colors")
public class MyController{
#RequestMapping("/{name}
public String myMappedMethod(#PathVariable("name") String name, ..){
}
}
So now, this method will be handled by the call to /controller/colors/blue etc.
I don't necessarily want the web pages to be built with JSP
Spring MVC offers many view template integration options, from passthrough to raw html to rich templating engines like Velocity and Freemarker. Perhaps one of those options will fit what you're looking for.

Resources