Spring 5 + Tomcat standalone - truncated response - spring

I have application written in Spring Boot 2 and REST API. When I run this app on embeded Tomcat server via bootRun gradle task everything is fine.
The problem is that when this application is deployed on standalone Tomcat 8.5 server response is truncated to 8kB. Why is that?
My REST controller:
#RestController
public class ApiController {
public ResponseEntity<Mono<ResultData>> get(String param) {
// generating data
return ResponseEntity.ok(Mono.just(ResultData.builder()
.data(data)
.build()));
}
}

Solved. I have not extended SpringBootServletInitializer (https://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html) - when you would like to run Spring Boot app as deployable war you have to do this.

Related

GORM Data Services are not injected when deployed to Tomcat

Why are GORM Data Services are not injected into ordinary Grails services when deployed to Tomcat?
We have a couple of domain/service/dataservice sets like the following:
//grails-app/services
class BeerService {
BeerDataService beerDataService
List<BeerEntity> list() {
beerDataService.list() << throws NPE
}
}
//grails-app/services
#grails.gorm.services.Service(BeerEntity)
interface BeerDataService {
List<BeerEntity> list()
}
//grails-app/domain
class BeerEntity {
String type
}
This works as expected using bootRun or as a runnable jar (in any environment), but when deployed in Tomcat (8 or 9) the data services are not registered as beans (aka. not present in applicationContext).
Using them therefore results in NPE’s.
Fetching them from the applicationContext directly (via #Autowired or Holders) results in NoSuchBeanDefinitionException being thrown.
I’ve verified the problem in a sample project (using generate-all) deployed to a local Tomcat 8 using different Java 8 versions.
Data Services are not injected when running in Tomcat, neither in controllers nor other services.
Any thoughts on why?
I’m completely lost!
Environment:
Java: 8.0.322-tem and 8.0.302-open
Tomcat: 9.0.31 and 8.5.78
OS: Ubuntu 20.04
From gradle.properties:
grailsVersion=5.1.7
groovyVersion=3.0.7
gorm.version=7.2.1

Spring Boot App as .war is running, but endpoint is not working

I built a Spring Boot Rest API and want it to run in a Tomcat container on a Linux server.
I have a server on digitalocean running on Ubuntu 20.4
I installed tomcat as described in this article and it is running
I build a very small Spring Boot Application with only one endpoint, which I want to build and deploy on the tomcat server. You can see the build.gradle file here in my github repository: spring-boot-example
Here are some Code Snippets:
#RestController
public class ExampleController {
#GetMapping(value = "/hello-world")
public ResponseEntity<String> helloWorld() {
return ResponseEntity.ok("Hello world");
}
}
#SpringBootApplication
public class ExampleApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ExampleApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class);
}
}
This is basically the whole app
Steps taken:
building the war file with './gradlew war' or './gradlew bootWar' locally on my machine (I tried both, i don't know if it makes any difference, but I had the issue with both of them)
Opening the tomcat manager remotely on http://'host':8080/manager/html
Deploying the .war file manually and waiting until it's deployed:
As you can see, it is up and running:
Now I open the following URL: http://host:8080/spring-boot-example/hello-world, where I expect to see the message Hello world, as defined in the Controller
But all I can see is this
Did I miss something? It says at the end or is not willing to disclose that one exists, do I have to do something with that endpoint to make it available to the public? Or did I upload the app incorrectly?

Spring boot, tomcat, rest api 404

I am using Kotlin + Gradle and trying to build a war file to deploy on Tomcat. My application is from the https://start.spring.io plus a simple controller and build the war file using ./gradlew bootWar
#SpringBootApplication
class ServletInitializer : SpringBootServletInitializer() {
override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
return application.sources(DemoApplication::class.java)
}
}
#RestController
class TomcatController {
#GetMapping("/hello")
fun sayHello(): Collection<String> {
return IntStream.range(0, 10)
.mapToObj { i: Int -> "Hello number $i" }
.collect(Collectors.toList())
}
}
when I try to access it I get
Type Status Report
Message The requested resource [/demo-0.0.1-SNAPSHOT/hello] is not available
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
I am super stuck. What am I doing wrong? If I add a html file to the src/main/webapp/index.html it shows up for some reason only the rest api can't be reached.
Spring Boot applications come with a built in Servlet. You are probably already using this feature when launching the application inside your IDE.
This basically means that you can just run your .jar file on any web server and it will be ready to go without setting up an extra tomcat instance.
However, if you want to build a Spring Boot application as a war file and deploy it to an external tomcat, you need to follow some extra steps as explained in this article.
Assuming from what you posted so far: the path that is returned shows another route before your actual controller route "/demo-0.0.1-SNAPSHOT/hello" is this "/demo-0.0.1-SNAPSHOT" the path that your application runs on ? If not it should be included in your controller (assuming you havent set it elsewhere for e.g. in your application.properties).
for e.g. http://localhost:8080/ would be the basepath and either http://localhost:8080/demo-0.0.1-SNAPSHOT/hello or http://localhost:8080/hello would point to your controller. Also your startup logs (for Tomcat and Spring) might give away more about the issue.

Accessing tomcat management page from Spring tool set 4

I have developed a Camel Rout using Spring. I used the STS4 IDE to develop the same.
When I started the application using Run As-> Spring Boot App, the application starts and also I can see from the logs that the route is started.
My route is a basic app, the exposes a rest endpoint and logs a Hello World
#Override
public void configure() throws Exception {
restConfiguration()
.enableCORS(true)
.apiContextPath("/api-doc")
.apiProperty("api.title", "Test REST API")
.apiProperty("api.version", "v1")
.apiContextRouteId("doc-api")
.component("servlet")
.bindingMode(RestBindingMode.json);
rest("/api/")
.id("api-route")
.consumes("application/json")
.get("/test")
.to("direct:log");
from("direct:log")
.id("log")
.log(LoggingLevel.INFO,"Test successful");
}
What I am expecting is that if I do localhost:8080/api/test, i will see some logs "Test Susccessful" in the Tomcat logs. I am using tomcat 9, Instead what I get WhiteLable error. I thought there is an issue with my code so I tried localhost:8080 and i was expecting the Tomcat Management server to open. Even that is not working.
I am not starting Tomcat separately. What I am doing is Run As-> Spring Boot App and I guess it is calling the embedded tomcat.
Credit for this answer goes to #Bedla. I had to add camel in the URL path http://localhost:8080/camel/api/test

Starting Spring boot REST controller in two ports

Is there a way to have two rest controller running on two different ports from one spring boot application ?
Say for example Controller_A running in http://localhost:8080 and Controller_B running in http://localhost:9090 in one SpringBoot main Application ?
One way of doing this is actually creating two application properties;
app-A.properties
server.port=8080
app-B.properties
server.port=9090
And then in your controllers, put annotation like below;
#Profile("A")
public class ControllerA {
...
}
#Profile("B")
public class ControllerB {
...
}
Finally you need to launch your application twice with following settings;
java -jar -Dspring.profiles.active=A awesomeSpringApp.jar
java -jar -Dspring.profiles.active=B awesomeSpringApp.jar

Resources