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.
Related
I have added basic authentication in my Rest API. My API is CRUD. I have changed the username and password. When I apply the GET, GET by id parameter and POST, they are working flawlessly but when I call the PUT and DELETE, I get 401 unauthorized. I have checked the username and password for they are correct or no. There is no problem about it. What is the reason about this issue?
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 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>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xyztq</groupId>
<artifactId>TodoApp2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TodoApp2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.project.lombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
SecurityConfiguration class
#Configuration
#EnableWebSecurity
public class SecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.httpBasic();
http.formLogin();
http.authorizeHttpRequests().requestMatchers("/todos").authenticated().and()
.csrf().ignoringRequestMatchers("/todos")
.and().authorizeHttpRequests().requestMatchers("/todos/{id}").authenticated().and()
.csrf().ignoringRequestMatchers("/todos/{id}");
return http.build();
}
This is my controller
#RestController
#RequestMapping("/todos")
#AllArgsConstructor
public class TodoController {
private final TodoService todoService;
#GetMapping
public ResponseEntity<List<Todo>> getTodos(#RequestParam(required = false) String title){
return new ResponseEntity<>(todoService.getTodos(title), OK);
}
#GetMapping("/{id}")
public ResponseEntity<Todo> getTodo(#PathVariable String id){
return new ResponseEntity<>(todoService.getTodoById(id), OK);
}
#PostMapping
public ResponseEntity<Todo> createTodo(#RequestBody Todo todo){
return new ResponseEntity<>(todoService.createTodo(todo), OK);
}
#PutMapping("/{id}")
public ResponseEntity<Void> updateTodo(#PathVariable String id,#RequestBody Todo todo){
todoService.updateTodo(id,todo);
return new ResponseEntity<>(OK);
}
#PatchMapping("/{id}")
public ResponseEntity<Void> updateDoneTodo(#PathVariable String id,#RequestBody Todo todo){
todoService.patchTodo(id,todo);
return new ResponseEntity<>(OK);
}
#DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTodo(#PathVariable String id){
todoService.deleteTodo(id);
return new ResponseEntity<>(OK);
}
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 making a POST request to authenticate the API that I'm implementing, but I have the following problem:
My username is not being returned:
however, my password is, and I'm not understanding why:
Below I will be sending my source code for better understanding...
Class: AuthController.java
#RestController
#RequestMapping("/auth")
public class AuthController {
#Autowired
AuthenticationManager authenticationManager;
#Autowired
JwtTokenProvider jwtTokenProvider;
#Autowired
UserRepository repository;
#ApiOperation(value = "Authenticate a user by credentials") //Swagger endpoint description
#PostMapping(value="/signin", produces = { "application/json", "application/xml", "application/x-yaml" }, consumes = {
"application/json", "application/xml", "application/x-yaml" })
public ResponseEntity singin(#RequestBody AccountCredentialsVO data) throws Exception {
try {
var username = data.getUserName();
var password = data.getPassword();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
var user = repository.findByUserName(username);
var token = "";
if(user != null) {
token = jwtTokenProvider.createToken(username, user.getRoles());
}else {
throw new UsernameNotFoundException("Username " + username + " not found!");
}
Map<Object, Object> model = new HashMap<>();
model.put("username", username);
model.put("token", token);
return ok(model);
} catch (Exception e) {
throw new BadCredentialsException("Invalid username/password supplied!");
}
}
}
Class: AccountCredentialsVO.java
public class AccountCredentialsVO implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "username")
private String username;
private String password;
public String getUserName() {
return username;
}
public void setUserName(String userName) {
this.username = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
return Objects.hash(password, username);
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AccountCredentialsVO other = (AccountCredentialsVO) obj;
return Objects.equals(password, other.password) && Objects.equals(username, other.username);
}
}
The pom.xml:
<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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.andrefilipeos</groupId>
<artifactId>rest-with-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<description>Creating API RESTFul with Spring Boot 2.x</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- for Spring-boot Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- for Tests Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
<version>6.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- for XML support-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- for YML or YAML support-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<!-- for HATEOAS Support -->
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<!-- for Swagger Support -->
<!-- http://localhost:8080/v2/api-docs -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- it's format all API documentation organized -->
<!-- http://localhost:8080/swagger-ui.html -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- for Security Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for Tokens Support -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!-- for Migration support $mvn flyway:migrate -->
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<configuration>
<url>jdbc:mysql://localhost:3306/rest_with_springboot?useTimezone=true&serverTimezone=UTC&useSSL=false</url>
<user>root</user>
<password>admin123</password>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
My POST request:
http://localhost:8080/auth/signin
With XML (application/xml):
<AccountCredentialsVO>
<username>leandro</username>
<password>admin123</password>
</AccountCredentialsVO>
With JSON (application/json):
{
"username":"leandro",
"password":"admin123"
}
And unfortunately with both requests I'm getting the same result of null username!
I'm trying to make a Spring Boot Application with simple login page but when i try to use #Autowired with a interface that i created seems to be a problem. I read 7-8 similar questions but the answers that i find there was useless for me. #Autowired works fine when i use it on interface that expends JpaRepository.
my structure is:
My packages are on the same level as my Application file .
Here is my controller
#Controller
#RequestMapping(value = "/users")
public class LoginContoller {
#Autowired
UsersRepositoryCustom usersRepositoryCustom;
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginForm(){
return "login";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public #ResponseBody
String verifyLogin(#RequestParam String name, #RequestParam String password) {
System.out.println("Controller: name: " + name + " pass " + password);
Users users=usersRepositoryCustom.loginUser(name, password);
if (users==null) {
System.out.println("login control user null");
return "login";
}
return "users/all";
}
}
Repository:
#Repository
public interface UsersRepositoryCustom {
Users loginUser(String name, String password);
}
I do not think it helps but here is the implementation
public abstract class UserImpl implements UsersRepositoryCustom {
#Autowired
UsersRepository usersRepository;
#Override
public Users loginUser(String name, String password) {
System.out.println("UserImpl: nume: " + name + " pass " + password);
Users user=usersRepository.findByUsername(name);
if (user != null && user.getPassword().equals(password)) {
System.out.println("User Login"+user.getId()+" "+user.getUsername());
return user;
}
return null;
}
}
Application.properties:
server.port=8080
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url= jdbc:mysql://localhost:3308/assignment-one-db
spring.datasource.username=root
spring.datasource.password=789456123
spring.jpa.hibernate.ddl-auto= update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.asg1</groupId>
<artifactId>asg1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>asg1</name>
<description>assignment1</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.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>10</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-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>
I try to use #EnableJpaRepositories, #EnableAutoConfiguration but it was useless
Here is the error:
Description:
Field usersRepositoryCustom in com.asg1.asg1.controllers.LoginContoller required a bean of type 'com.asg1.asg1.repository.UsersRepositoryCustom' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.asg1.asg1.repository.UsersRepositoryCustom' in your configuration.
Process finished with exit code 1
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.