Starting Spring boot REST controller in two ports - spring

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

Related

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.

Spring 5 + Tomcat standalone - truncated response

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.

Spring Boot: specify port at the mapping level

Spring Boot: I want to have achieved the following: some URL paths are mapped to a port, some to another.
In other words I'd like something like:
public class Controller1 {
#RequestMapping(value="/path1", port="8080") public...
#RequestMapping(value="/path2", port="8081") public...
}
So that my app responds to both localhost:8080/path1 and localhost:8081/path2
It's acceptable to have 2 separate controllers within the app.
I have managed to partially succeed by implementing an EmbeddedServletContainerCustomizer for tomcat, but it would be nice to be able to achieve this inside the controller if possible.
Is it possible?
What you are trying to do would imply that the application is listening on multiple ports. This would in turn mean that you start multiple tomcat, since spring-boot packages one container started on a single port.
What you can do
You can launch the same application twice, using different spring profiles. Each profile would configure a different port.
2 properties:
application-one.properties: server.port=8080
application-two.properties: server.port=8081
2 controllers
#Profile("one")
public class Controller1 {
#RequestMapping(value="/path1") public...
}
#Profile("two")
public class Controller2 {
#RequestMapping(value="/path2") public...
}
Each controller is activated when the specified spring profile is provided.
Launch twice
$ java -jar -Dspring.profiles.active=one YourApp.jar
$ java -jar -Dspring.profiles.active=two YourApp.jar
While you cannot prevent making call on the undesired port, you can specify HttpServletRequest among other parameters of the method of the controller, and then use HttpServletRequest.getLocalPort() to obtain the port the call is made on.
Then you can manually return the HTTP error code if the request is made on the wrong port, or forward to another controller if the design is such that same path on different ports must be differently processed.

Configure Spring Boot application to use MongoDB connection uri provided in environment variable

I would like to configure the connection-uri to my MongoDB through an environment variable. This way, I can set different values on localhost or if the Spring Boot application is running in a cloud.
I have included mongodb in my build.gradle file:
dependencies {
compile 'org.springframework.cloud:spring-cloud-spring-service-connector:1.2.2.RELEASE'
compile("org.springframework.boot:spring-boot-starter-data-mongodb")
...
}
To work locally, I have currently set the spring.data.mongodb.uri=mongodb://... in applications.properties but I would rather like to have that value read from an environment variable. How can I achieve this?
I have read articles about Spring Boot and Cloud suggesting extending the AbstractCloudConfig somehow like this:
public class CloudConfig extends AbstractCloudConfig {
#Bean
public MongoDbFactory documentMongoDbFactory() {
return connectionFactory().mongoDbFactory();
}
}
But I assume this wouldn't work with environment variables and working locally.
You should use profiles to do that.
Read about profiles
Read how to use Profiles
How to Set Profiles

Spring Boot: Change Port for Web Application

I am currently trying to create a web application with Spring Boot. I need to host my application to localhost:8081. How do I change the port?
Actually you want to change server.port and you can change it in many different ways as described http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config
Examples:
in your application.properties (in or outside the jar)
command line
java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar
and much more
By default spring boot uses port 8080, BUT you can change the port just by adding the following code line in your main() like this:
System.getProperties().put( "server.port", *YOUR_PORT_NUMBER_GOES_HERE* );
e.g
#SpringBootApplication
public class MyClass {
public static void main(String[] args) {
System.getProperties().put( "server.port", 8181 ); //8181 port is set here
SpringApplication.run(MyClass.class, args);
}
OR
You can configure it in your application.properties file like so:
server.port=8181
If you DON'T have an application.properties file in your spring-boot application, you can go ahead and create one. Right-click on the src/java/resources folder and go to New-> Other-> General and choose 'File' then name as: application.properties
Any other configurations you might need are listed here https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html. These properties are also configured in the application.properties file.
Actually you want to change server.port and you can change it in many different ways as described
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config
Put server.port=9000 in your application.properties
In your application.properties file, just add one line
server.port = 8080
And for more configurations you can refer Spring Boot documentation on port
If you are using the embedded tomcat server, you can configure the EmbeddedServletContainerFactory bean yourself in your Application class annotated with #SpringBootApplication.
This will give you options to customize your tomcat server, example configuration
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}
You could also do the same for Jetty, using the JettyEmbeddedServletContainerFactory bean, or for Undertow using the UndertowEmbeddedServletContainerFactory .
Official documentation found here : http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/
If you're using STS, you can do it following below steps:
Go to Boot Dashboard view, you'll see your Boot app, say myApp1
Right click and click on Open Config. This should open Run Time
Configuration section.
Go to Argument tab and add parameter server.port=, like in the example below, a custom port 9091 is added.
Start the app and if everything is good, you'll see the desired port
on Boot dashboard.
go to your application.properties file and type server.port=8081
see this image

Resources