Spring value binding in #RequestMapping - java

I have a health check controller like the below one:
#RestController
#RequestMapping("/api/${app-name}/management")
public class HealthCheckController {
#GetMapping(path = "health", produces = MediaType.TEXT_PLAIN_VALUE)
public Mono<String> healthCheck() {
return Mono.just("Ok");
}
}
I have this controller in a common library and this library is included in all our services. In each service properties, I have given the value for app-name. So the URLs like http://host:port/api/service1/management/health will return Ok. This is working fine on my local machine but on the server, getting a 404 error. Our services are deployed in Kubernetes.
Am I missing anything here? Was the value binding in #RequestMapping (${app-name}) is correct usage?

Related

Read JWT token in Spring Boot RouterFunction

In Spring Boot Controller implementation we can get the JwtAuthenticationToken as a parameter in our method. Same token can be read, manipulated and validated for authorization like below
#PostMapping("/hello")
#PreAuthorize("hasAuthority('SCOPE_Internal') or hasAuthority('ROLE_User')")
public Mono<String> testHello(JwtAuthenticationToken token) {
log.info("token is " + token.getTokenAttributes().toString());
return Mono.just("OK");
}
We are using reactive Spring Boot and we have replaced our controllers with RouterFunction. We are wondering how above feature - Authorization and get the token in our router method calls.
public RouterFunction<ServerResponse> route() {
return RouterFunctions.route(GET("/hello"), helloHandler::testHello);
}
When we tried passing the JwtAuthenticationToken in the router method call, it threw
Could not autowire. No beans of 'JwtAuthenticationToken' type found.
public RouterFunction<ServerResponse> route(JwtAuthenticationToken jwtAuthenticationToken) {
return RouterFunctions.route(GET("/hello"), helloHandler::testHello);
}
We came up this solution if it makes any sense, or valid. We ran into same issue lately as we began a journey of converting our legacy and synchronous spring boot server app to an asynchronous one. The JwtAuthenticationToken which we use to get some added attribute to the token used by the system works out of the box when we used the RestController and pass it as an argument in the protected endpoint method. But with Router Function we could not get it to work. After 1 day of painstaking research on google, stackoverflow, spring's reactive application resource server docs, we could not get any head way. However, this post got us thinking even more. so we came up with this solution:
#Slf4j
#Component
#RequiredArgsConstructor
public class FitnessAccountWebHandler {
private final FitnessAccountService accountService;
public Mono<ServerResponse> getAccountByUserId(ServerRequest request) {
String userId = request.pathVariable(AccountResourceConfig.USER_ID);
// This will give you the JwtAuthenticationToken if a Principal is
// returned or empty if no authentication is found
Mono<JwtAuthenticationToken> authentication = request
.principal()
.cast(JwtAuthenticationToken.class);
return authentication.flatMap(auth -> {
log.info("Subject: {}", auth.getName());
return accountService.getSomething(userId)
.flatMap(ServerResponse.ok()::bodyValue)
.switchIfEmpty(ServerResponse.notFound().build());
});
}
}
Hope this helps someone and save some time.

Spring Boot - Rest Api occasionally adds Error Object to a response

I use spring-boot-starter-web (Spring Boot 2.3.0.RELEASE) and my Controller looks like:
#RestController
#RequestMapping(value = "/v1")
public class Controller {
#GetMapping
public ResponseEntity<Object> getObject() {
return ResponseEntity.ok(new Object());
}
}
I've noticed that sometimes in a browser I catch a response like
{}{"timestamp":"2021-03-11T13:39:08.100+00:00","status":200,"error":"OK","message":"","path":"/v1"}
This reproduces randomly - most time I get a correct JSON {}.
Could you advise how to disable adding of the second JSON and what can be a reason for this behavior? Is it a bug?

Single Spring mvc 4 controller with no #RequestMapping returns strips css from my html view

I have a simple controller in a spring boot mvc app packaged as a .war (for aws deployment). I have Thymeleaf on the build path and bootstrap 3.3.6 in resources/static folder. I use #EnableAutoConfiguration in the main.
This controller displays a view just fine.
#Controller
#RequestMapping(value = "/handeware")
public class HomeController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String viewHome() {
return "home";
}
}
However, when I remove the #RequestMapping part like this
#Controller
public class HomeController {
#RequestMapping(method = RequestMethod.GET)
public String viewHome() {
return "home";
}
}
It appears that the view gets returned with the Bootstrap CSS styling stripped.
Essentially, I have a domain name www.blah.com with the CNAME pointing to my spring mvc app hosted in aws elastic beanstalk. The idea is that I want someone to be able to type www.blah.com into the browser and be able to see my home page. In order to do this, I removed the #RequestMapping's from my controller, and it works. People can now visit my site at www.blah.com and see my home.html. However, the CSS styling is not showing up now. If I add the #RequestMapping back, the CSS shows back up. Isn't that odd? I confirmed in my local as well as in aws that this is the case. Not sure what to make of it.
How do you reference your css files from your html? You may need to update those references to match the new path.

POST method in Spring Boot REST service (external Tomcat) return 404 error

I created a REST web service using Spring Boot.
The project is configured to use an external Tomcat.
When using Tomcat 8 it connects successfully and get good responses when i call my GET methods.
However, the POST methods return 404 errors.
#RestController
#RequestMapping("/hashkey")
#EnableAutoConfiguration
public class StringHashingController {
#RequestMapping(method=RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody HashedStringsList hashMe(#RequestParam(value="caller", required=true) String callerId, #RequestBody StringHashingRequestBodyParams hashParam) {
HashedStringsList pList = new HashedStringsList();
//...
return pList;
}
}
I have no problem calling the same post method locally in the IDE (Intellij) through running 'Spring Boot Configuration'.
Is there anything I need to configure in Tomcat or in my code?
Thanks!

Spring REST Service - Set the Root URI

New to spring and have a question regarding setting the Rest URI path.
I have a working rest service and I would like to change the URI from something like http://localhost:8080/myapp/api to http://localhost:8080/api
Normally I would do this with an annotation such as: #ApplicationPath("api") but that doesnt seem to be applicable, tried the below but doesnt give the desired result.
TestController.java
#Controller
#RequestMapping("api")
public class TestController {
#RequestMapping("/test")
public #ResponseBody Test Test() {
return new Test("Test String");
}
}
How can this be done with spring?
Generally configured in META-INF/context.XML. Set path to / or "".
Here's a similar issue with tomcat 7
HOWTO set the context path of a web application in Tomcat 7.0

Categories