Spring Boot | parsing Url with query params in properties file with URIComponentBuilder - spring

I have a URL in my application-local.properties file which looks like
basePath: http://host.com/
endpoint: /endpoint?q={value1}
I am mapping it to variables in a class annotated with #ConfigurationProperties. I am using URLComponentBuilder to build the full URL like this:
UriComponentsBuilder.fromUriString(basePath).path(properties.endpoint).build(123)
The URL I am getting is this: http://host.com/endpoint%3Fq=123 i.e. the ? gets encoded.
The question is that I don't want to remove query params from the properties file and add them only in the code where I am building the URL. I want to keep the full URI endpoint in the properties file and still be able to generate the correct (without ? being encoded) full URL through URIComponentBuilder

Related

How to remove context-root from generated swagger

I have am application that has a context-root set (property: quarkus.http.root-path).
Using quarkus-resteasy-reactive-jackson, a resource was created with a #Path annotation.
Now I want to generate OpenAPI documentation for my resource.
As I want to deploy this into a API gateway, I require a server property with a context root in the swagger.
I added a server entry using the mp.openapi.servers property.
The problem now appears that when there is a root-path property, the generated swagger resource path includes this root path, e.g.
quarkus.http.root-path=/sample
mp.openapi.servers=http://localhost:8080/sample
Resource annotated with #Path("resource")
It seems that the resource path includes the root-path.
So importing this swagger into the API gateway (or just clicking on the Try button), results in a url of http://localhost:8080/sample/sample/resource being attempted which ofc does not exist.
Is there a way to not to add the root-path to the resource endpoint in swagger? (I tried using mp.openapi.extensions.application-path.disable=true, but this had no effect)
I managed to get past this by doing the following:
dont set quarkus.http.root-path
quarkus.rest.path=/sample
quarkus.http.non-application-root-path=/sample/q
mp.openapi.servers=https://localhost:8080/sample
So just want to know if anyone know of a better way of doing this?

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

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})

Swagger not generating paths in yaml/json file when code is compiled

Trying to generate API documentation for a spring boot application using swagger. Using swagger-maven-plugin to generate yaml documentation from code. After compiling, the generated yaml/json file does not contain any path. However the controller class where the APIs are defined is getting scanned. But none of the APIs defined there are showing up in documentation. However accessing http://localhost:8080/api-docs shows a json and that is listing all the APIs as expected. What could be the issue? I have made sure of the following:
controller is annotated with #Api
tag value is set to false in pom.xml
basepath is the same across pom and controller class
All API paths are of the form http://localhost:8080/{id}/
Got my problem resolved. The Controller class methods were not declared public and hence was not showing up in swagger.yaml and json files even though the api-docs were listing them.
Try mapping your controller into a path.
Eg:- #Controller #RequestMapping(value = "/api")
For further clarification you can refer this article: https://www.baeldung.com/spring-controllers

How can I ingore placeholders in property file in spring boot?

I have urls like localhost:8080/boot/${task}/say
in property file, I am reading this url in my code using poprerty placeholder, problem is here spring boot trying to search placeholder in url. I want to ingore that and send complete url with that placeholder into response.
I have already declared bean of PropertySourcePlaceholderConfigure and setIgoreUnresolvablePlaceholders as true but still it asking for value of placeholder.
You need to escape $ sign.
localhost:8080/boot/#{'$'}{task}/say

Why is plus(+) decoded to space ( ) in url path with springboot rest controller?

When calling GET http://localhost:8080/things/ZhaD2lk27XQPRJtwrABltd+UTWXcbnY%2FTrpxGP7VDVo= my Spring Boot application RestController with a request handler like this:
#RequestMapping("/things/{thingId}")
public ResponseEntity<Thing> getThing(
#PathVariable String thingId) {
System.out.println("thingId=" + thingId);
...
results in the following being printed ZhaD2lk27XQPRJtwrABltd UTWXcbnY/TrpxGP7VDVo= instead of what I would have expected ZhaD2lk27XQPRJtwrABltd+UTWXcbnY/TrpxGP7VDVo=.
As you can see, the plus is being turned into a space. This should not happen with the path part, only the query part. This is why the Spring UriComponentsBuilder.build().encode() I'm using to build the URL doesn't turn the plus into %2B.
I needed to tweak the application already to get the encoded slash (/) to work. See REST Endpoint unreachable if ID in URL contains %2F for details.
I'm using SpringBoot 1.4.4.RELEASE which uses Tomcat embed 8.5.11.
I have tried calling the service from Spring RestTemplate, Postman and Chrome. Same results in all cases, the plus is turned into a space
I was able to resolve after identifying that my IDE had automagically added spring-boot-starter-undertow to the POM file. I did not exclude spring-boot-starter-tomcat from spring-boot-starter-web so I'm not sure what was happening under the covers but removing the spring-boot-starter-undertow dependency fixed the issue.

Resources