I recreate a spring boot simple project "greetings", and when i run it On server, it work and i get JSON data in the browser like this:
localhost:9090/api/greetings
and it show:
[{"id":1,"text":"Hello world1"},{"id":2,"text":"Hello world2"}]
and i generate successfully the war file via console :
...\workspace-sts-3.8.0.RELEASE\demo>mvn clean install
and I have already set up tomcat7 on my ubuntu server 14.04 tls,
and throw the web manager I select the war file to deploy on the server:
but when tap the url to show all greetings for example, it doesn't show anything:
error : the requested resource type is not valid
so i check the error in the tomcat 7 catalina.out log:
INFO: Deploying web application archive /var/lib/tomcat7/webapps/demo-0.0.1-SNAPSHOT.war
Jul 28, 2016 7:38:55 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/var/lib/tomcat7/webapps/demo-0.0.1-SNAPSHOT/WEB-INF/lib/javax.el-3.0.0.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class
Jul 28, 2016 7:38:55 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/var/lib/tomcat7/webapps/demo-0.0.1-SNAPSHOT/WEB-INF/lib/javax.servlet-api-3.1.0.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class
Jul 28, 2016 7:38:55 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/var/lib/tomcat7/webapps/demo-0.0.1-SNAPSHOT/WEB-INF/lib/tomcat-embed-el-8.0.36.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class
But i did't understand what's the issue exactly,
this is my project structure :
project structure
and this is my java classes:
1/class DemoApplication
#SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
}
2/class Greeting
public class Greeting {
private BigInteger id;
private String text;
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
3/class GreetingController
#RestController
public class GreetingController {
private static BigInteger nextId;
private static Map<BigInteger, Greeting> greetingMap;
private static Greeting save(Greeting greeting){
if(greetingMap == null){
greetingMap = new HashMap<BigInteger, Greeting>();
nextId = BigInteger.ONE;
}
//if update....
if(greeting.getId() != null){
Greeting oldGreeting = greetingMap.get(greeting.getId());
if(oldGreeting == null){
return null;
}
greetingMap.remove(greeting.getId());
greetingMap.put(greeting.getId(), greeting);
return greeting;
}
// if create....
greeting.setId(nextId);
nextId = nextId.add(BigInteger.ONE);
greetingMap.put(greeting.getId(), greeting);
return greeting;
}
static {
Greeting g1 = new Greeting();
g1.setText("Hello word");
save(g1);
Greeting g2 = new Greeting();
g2.setText("Hello samsa");
save(g2);
}
#RequestMapping(
value="/api/greetings",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Greeting>> getGreetings(){
Collection<Greeting> greetings = greetingMap.values();
return new ResponseEntity<Collection<Greeting>>(greetings, HttpStatus.OK);
}
#RequestMapping(
value="/api/greetings/{id}",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> getGreeting(#PathVariable("id") BigInteger id){
Greeting greeting = greetingMap.get(id);
if(greeting == null){
return new ResponseEntity<Greeting>(greeting, HttpStatus.NOT_FOUND);
}
return new ResponseEntity<Greeting>(greeting, HttpStatus.OK);
}
#RequestMapping(
value="/api/greetings",
method=RequestMethod.POST,
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> createGreeting(#RequestBody Greeting greeting){
Greeting savedGreeting = save(greeting);
return new ResponseEntity<Greeting>(savedGreeting, HttpStatus.CREATED);
}
#RequestMapping(
value="/api/greetings/{id}",
method=RequestMethod.PUT,
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> updateGreeting(#RequestBody Greeting greeting){
Greeting updatedGreeting = save(greeting);
if(updatedGreeting == null){
return new ResponseEntity<Greeting>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<Greeting>(updatedGreeting, HttpStatus.OK);
}
private static boolean delete(BigInteger id) {
Greeting deletedGreeding = greetingMap.remove(id);
if(deletedGreeding == null){
return false;
}
return true;
}
#RequestMapping(
value="/api/greetings/{id}",
method=RequestMethod.DELETE,
consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> deletedGreeting(#PathVariable("id") BigInteger id, #RequestBody Greeting greeting){
boolean deleted = delete(id);
if(!deleted){
return new ResponseEntity<Greeting>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<Greeting>(HttpStatus.NO_CONTENT);
}
}
and this is the pom file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
It is possible that you did not set your context path on application.properties and therefore Tomcat is using the default path of the application name.
Add server.contextPath=/ to the properties file to set the context path for the embedded tomcat and for the external tomcat add the context.xml with the below to your project to set the context path.
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/"/>
Related
How to correctly use DynamoDB with Spring?
I tried to follow many tutorials but always got the same error.
For example my realization of [baeldung tutorial][1]:
application-properties:
#AWS-creds
amazon.dynamodb.endpoint=https://dynamodb.us-east-1.amazonaws.com
amazon.aws.accesskey=
amazon.aws.secretkey=
spring.jpa.hibernate.ddl-auto=create
spring.main.allow-bean-definition-overriding=true
configuration:
#Configuration
#EnableDynamoDBRepositories
(basePackages = "com.hrzc.demo.repository")
public class DynamoDBConfig {
#Value("${amazon.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
#Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
#Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
#Bean
public AmazonDynamoDB amazonDynamoDB() {
AmazonDynamoDB amazonDynamoDB
= new AmazonDynamoDBClient(amazonAWSCredentials());
if (!StringUtils.isEmpty(amazonDynamoDBEndpoint)) {
amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
}
return amazonDynamoDB;
}
#Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(
amazonAWSAccessKey, amazonAWSSecretKey);
}
}
entity:
#DynamoDBTable(tableName = "Url")
public class Url {
private int id;
private String longUrl;
#DynamoDBAttribute
#DynamoDBRangeKey
public String getLongUrl() {
return longUrl;
}
public void setLongUrl(String longUrl) {
this.longUrl = longUrl;
}
#DynamoDBHashKey
#DynamoDBAutoGeneratedKey
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
repository:
#EnableScan
public interface UrlRepository extends CrudRepository<Url, Long> {
}
The pom file does not equal the pom from the tutorial, but I hope this is not the reason, since I can't start the project with dependencyManagement - the error sounds like An attempt was made to call a method that does not exist. - and I found the suggestion to remove the spring-boot-data overriding [here][2].
pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hrzc</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>linkshrtnr</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.11.64</version>
</dependency>
<dependency>
<groupId>com.github.derjust</groupId>
<artifactId>spring-data-dynamodb</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I created the Url table via aws-cli:
> aws dynamodb describe-table --table-name Url
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "N"
},
{
"AttributeName": "longUrl",
"AttributeType": "S"
}
],
"TableName": "Url",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
},
{
"AttributeName": "longUrl",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2022-09-25T22:40:39.385000+03:00",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:us-east-1:393546347656:table/Url",
"TableId": "33f8baed-4d6c-4787-845d-1df7d0749cea"
}
}
So, how to use dynamoDB correctly?
[1]: https://www.baeldung.com/spring-data-dynamodb
[2]: https://stackoverflow.com/questions/64171751/spring-boot-refuses-to-start-problem-with-abstractrepositoryconfigurationsource
check your application properties file
#for mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#for postgres
#spring.datasource.driver-class-name=org.postgresql.Driver
my properties file is with other config is like
spring.datasource.name=localSource
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto = update
sometimes also check to update maven dependency by updating the maven (sts4/ eclipse)
I'm developing a web app with spring boot, I built the project with Maven.
In the project I use files .properties and I gave the path of the project like this:
Properties FileProperties = FileUtils.getProperties("src\main\resources\file.properties");
Running the project with IntelliJ, all work.
But at the moment I built with maven in Jar, and I open the web app, don't find the file properties and give NullPointerException.
This is my pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
This is the project map.
https://m.imgur.com/gallery/zZzTzID
Thanks so much
I tried this, but dont work.
ConfigProperties.java
package bperTube.transfer.Utils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
#Configuration
#PropertySource("classpath:file.properties")
#ConfigurationProperties(prefix = "upload")
public class ConfigProperties {
private String dateFormat;
private String directoryPath;
private String videoDirectory;
private String imageDirectory;
public String getDateFormat() {
return dateFormat;
}
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
public String getDirectoryPath() {
return directoryPath;
}
public void setDirectoryPath(String directoryPath) {
this.directoryPath = directoryPath;
}
public String getVideoDirectory() {
return videoDirectory;
}
public void setVideoDirectory(String videoDirectory) {
this.videoDirectory = videoDirectory;
}
public String getImageDirectory() {
return imageDirectory;
}
public void setImageDirectory(String imageDirectory) {
this.imageDirectory = imageDirectory;
}
}
file.properties
upload.dateFormat=dd-MM-yyyy
upload.directoryPath=/test/
upload.videoDirectory=swf/
upload.imageDirectory=poster/
In a Spring api, I have a method in a RestController for POST requests, however, when the request is made by Postman the system returns error 415:
{
"timestamp": "2019-07-02T18:08:48.859+0000",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'application/json;charset=UTF-8' not supported",
"path": "/api/call"
}
RestController class:
#RestController("/api/call")
public class CallController {
private final MailService mailService;
public CallController(MailService mailService) {
super();
this.mailService = mailService;
}
#PostMapping
public ResponseEntity<Void> postCall(#Valid #RequestBody Email formEmail) throws URISyntaxException {
mailService.sendMail();
return ResponseEntity.noContent().build();
}
}
Email class:
public class Email {
private static String MAIL_TO = "mail#email.com";
#Null
private String mailTo;
#NotNull
#Size(min = 3)
private String nameUserRequest;
#NotNull
#javax.validation.constraints.Email
private String emailUserRequest;
#NotNull
private String text;
public Email() {
super();
}
public String getMailTo() {
mailTo = MAIL_TO;
return mailTo;
}
public void setMailTo(String mailTo) {
this.mailTo = mailTo;
}
public String getNameUserRequest() {
return nameUserRequest;
}
public void setNameUserRequest(String nameUserRequest) {
this.nameUserRequest = nameUserRequest;
}
public String getEmailUserRequest() {
return emailUserRequest;
}
public void setEmailUserRequest(String emailUserRequest) {
this.emailUserRequest = emailUserRequest;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
#Override
public String toString() {
return "Email [nameUserRequest=" + nameUserRequest + ", emailUserRequest=" + emailUserRequest + ", text=" + text
+ "]";
}
}
Postman request:
The purpose is that the Post method only receives a Json for Email and returns success after sending the email, but it returns error 415, I tried #PostMapping(consumes ="application/json", produces="application/json") but it did not work. What is left for the system to accept Json requests?
Edited
My pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.company.mail.call</groupId>
<artifactId>mail-call</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>mail-call</name>
<description>Mail call</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
You should define the #RequestMapping("/api/call") on top of class to enable your route. #RestController("/api/call") that value inside #RestController defines the component name that will be managed by the Spring.
I am trying to embed a spring cloud server with git hub. Following this link right here.
Also following the following documentation
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-security</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
</dependencies>
...
HelloWorldApplication.java
#SpringBootApplication
#EnableConfigServer
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
HelloWorldController.java
#RestController
#RequestMapping("/hello")
#RefreshScope
public class HelloWorldController {
#Value("${prop1:default}") private String prop1;
#Value("${prop2:default}") private String prop2;
#RequestMapping(value = "/world", method = RequestMethod.GET)
public String getHelloWorld() {
return new StringBuilder()
.append("Message: ")
.append(prop1).append(" ")
.append(prop2).append("!")
.toString();
}
}
application.properties
server.port=8080
bootstrap.properties
spring.application.name=root-server
spring.cloud.config.server.bootstrap=true
spring.cloud.config.server.prefix=/config
spring.cloud.config.server.git.uri= www.githubrepo/config
spring.cloud.config.server.git.username = username
spring.cloud.config.server.git.password = password
Spring cloud GIT Repository file
${user.home}/Desktop/config/root-server.properties
prop1=Hello
prop2=World
Output
localhost:8080/hello/world
Message: default default!
It should be Message: Hello World!
I have already asked this question for Spring XD. I am now trying to migrate to Spring CDF.
I found this link and I tried to reuse the code there and change the encoding with mine.
I created the following POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>tcp-ber-source</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>TCP Ber Source</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<tcp-app-starters-common.version>1.1.0.RELEASE</tcp-app-starters-common.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud.stream.app</groupId>
<artifactId>tcp-app-starters-common</artifactId>
<version>${tcp-app-starters-common.version}</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>ber-byte-array-serializers</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Configuration:
#EnableBinding(Source.class)
#EnableConfigurationProperties(TcpBerSourceProperties.class)
public class TcpBerSourceConfiguration {
private final Source channels;
private final TcpBerSourceProperties properties;
#Autowired
public TcpSourceConfiguration(final TcpBerSourceProperties properties, final Source channels) {
this.properties = properties;
this.channels = channels;
}
#Bean
public TcpReceivingChannelAdapter adapter(#Qualifier("tcpBerSourceConnectionFactory") final AbstractConnectionFactory connectionFactory) {
final TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(connectionFactory);
adapter.setOutputChannel(this.channels.output());
return adapter;
}
#Bean
public TcpConnectionFactoryFactoryBean tcpBerSourceConnectionFactory(#Qualifier("tcpBerSourceDecoder") final AbstractByteArraySerializer decoder) throws Exception {
final TcpConnectionFactoryFactoryBean factoryBean = new TcpConnectionFactoryFactoryBean();
factoryBean.setType("server");
factoryBean.setPort(this.properties.getPort());
factoryBean.setUsingNio(this.properties.isNio());
factoryBean.setUsingDirectBuffers(this.properties.isUseDirectBuffers());
factoryBean.setLookupHost(this.properties.isReverseLookup());
factoryBean.setDeserializer(decoder);
factoryBean.setSoTimeout(this.properties.getSocketTimeout());
return factoryBean;
}
#Bean
public BerEncoderDecoderFactoryBean tcpBerSourceDecoder() {
final BerEncoderDecoderFactoryBean factoryBean = new BerEncoderDecoderFactoryBean(this.properties.getDecoder());
factoryBean.setMaxMessageSize(this.properties.getBufferSize());
return factoryBean;
}
}
And this FactoryBean:
public class BerEncoderDecoderFactoryBean extends AbstractFactoryBean<AbstractByteArraySerializer> implements ApplicationEventPublisherAware {
private final BerEncoding encoding;
private ApplicationEventPublisher applicationEventPublisher;
private Integer maxMessageSize;
public BerEncoderDecoderFactoryBean(final BerEncoding encoding) {
Assert.notNull(encoding, "'encoding' cannot be null");
this.encoding = encoding;
}
#Override
public void setApplicationEventPublisher(final ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* The maximum message size allowed when decoding.
* #param maxMessageSize the maximum message size.
*/
public void setMaxMessageSize(final int maxMessageSize) {
this.maxMessageSize = maxMessageSize;
}
#Override
protected AbstractByteArraySerializer createInstance() throws Exception {
final AbstractByteArraySerializer codec;
switch (this.encoding) {
case SPLIT:
codec = new ByteArrayBerSplitSerializer();
break;
case EXTRACT:
codec = new ByteArrayBerExtractSerializer();
break;
default:
throw new IllegalArgumentException("Invalid encoding: " + this.encoding);
}
codec.setApplicationEventPublisher(this.applicationEventPublisher);
if (this.maxMessageSize != null) {
codec.setMaxMessageSize(this.maxMessageSize);
}
return codec;
}
#Override
public Class<?> getObjectType() {
return AbstractByteArraySerializer.class;
}
}
BerEncoding is a simple enum, and TcpBerSourceProperties are pretty straightforward.
Is this the right approach?
If it is, how can I run this? I can't see #SpringBootApplication anywhere on the tcp stream app starters I found on the mentioned link to run as Spring Boot standalone applications?
You have to create your own Spring Boot App class and import the configuration class; see the documentation about creating custom apps.
We generate a standard app (for rabbit and kafka binders) from the starters as explained here.