I'm creating telegram-bot. When I use longpolling-bot it works correct, but I can't create bot that works on webhooks - http-request don't reach endpoint that has been registered as webhook-url in telegram.
For local deployment I use ngrok application.
I'm trying to send POST-request using Postman, which simulates an http-request from telegram-server, but the requests don't reach the method org.telegram.telegrambots.updatesreceivers.RestApi::updateReceived
This is the code:
build.gradle
plugins {
id "java"
id "org.springframework.boot" version "3.0.1"
id "io.spring.dependency-management" version "1.1.0"
}
repositories {
mavenCentral()
mavenLocal()
}
group 'com.example'
sourceCompatibility = JavaVersion.VERSION_17
def telegramBotVersion = "6.3.0"
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter'
implementation "org.telegram:telegrambots-spring-boot-starter:$telegramBotVersion"
implementation "org.telegram:telegrambotsextensions:$telegramBotVersion"
implementation 'javax.ws.rs:javax.ws.rs-api:2.0-m08'
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
}
package com.example.telegram.bot;
import com.example.telegram.service.TelegramService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.telegram.telegrambots.extensions.bots.commandbot.TelegramWebhookCommandBot;
import org.telegram.telegrambots.meta.api.objects.Update;
#Slf4j
public class WebhookBot extends TelegramWebhookCommandBot {
private final String name;
private final String token;
public WebhookBot(String name, String token) {
this.name = name;
this.token = token;
}
#Autowired
private TelegramService telegramService;
#Override
public String getBotUsername() {
return name;
}
#Override
public String getBotToken() {
return token;
}
#Override
public String getBotPath() {
return "webhookurl";
}
#Override
public void processNonCommandUpdate(Update update) {
System.out.println("processNonCommandUpdate");
}
}
package com.example.telegram.config;
import com.example.telegram.bot.WebhookBot;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.telegram.telegrambots.bots.TelegramWebhookBot;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import org.telegram.telegrambots.updatesreceivers.DefaultWebhook;
#Configuration
#Profile("webhook")
#Slf4j
public class WebHookBotConfig {
#Value("${telegram.bot.name}")
private String name; //bot-name
#Value("${telegram.bot.token}")
private String token; //bot-token
#Value("${telegram.bot.webhook.uri}")
private String webhookUri; // https://7b66-188-130-157-6.eu.ngrok.io/ for example
#Value("${telegram.bot.webhook.internalUrl}")
private String internalWebServerUrl; // http://localhost:8080
#Bean
public TelegramWebhookBot telegramWebhookBot() throws TelegramApiException {
DefaultWebhook defaultWebhook = new DefaultWebhook();
defaultWebhook.setInternalUrl(internalWebServerUrl);
TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class, defaultWebhook);
WebhookBot telegramBot = new WebhookBot(name, token);
SetWebhook setWebhook = new SetWebhook();
setWebhook.setUrl(webhookUri);
botsApi.registerBot(telegramBot, setWebhook);
return telegramBot;
}
}
./ngrok http 8080
Related
I have a Spring Boot App with the following classes in the src/main/java/in/javacoder/overlayapp package
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.13'
}
javafx {
version = "17"
modules = [ 'javafx.controls' ]
}
group = 'in.techpro424'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
CoordinateOverlayAppApplication.java
package in.techpro424.coordinateoverlayapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class CoordinateOverlayAppApplication {
public static void main(String[] args) {
SpringApplication.run(CoordinateOverlayAppApplication.class, args);
}
}
CoordinateRestController.java
package in.techpro424.coordinateoverlayapp;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class CoordinateRestController {
public static double xCoord;
public static double yCoord;
public static double zCoord;
#PostMapping(value = "/coordinateOverlay")
public int receiveCoordinates(#RequestParam(name = "xCoordinate") Double xCoordinate, #RequestParam(name = "yCoordinate") Double yCoordinate, #RequestParam(name = "zCoordinate") Double zCoordinate) {
CoordinateRestController.xCoord = xCoordinate;
System.out.println(CoordinateRestController.xCoord);
CoordinateRestController.yCoord = yCoordinate;
System.out.println(CoordinateRestController.yCoord);
CoordinateRestController.zCoord = zCoordinate;
System.out.println(CoordinateRestController.zCoord);
javafx.application.Application.launch(RenderCoordinateOverlay.class);
return 1;
}
}
RenderCoordinateOverlay.java
package in.techpro424.coordinateoverlayapp;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class RenderCoordinateOverlay extends Application {
double radius = 50;
#Override
public void start(Stage primaryStage) {
Group root = new Group();
Text coordinates = new Text();
coordinates.setText("X:" + CoordinateRestController.xCoord + ", Y:" + CoordinateRestController.yCoord + ", Z:" + CoordinateRestController.zCoord);
root.getChildren().add(coordinates);
Scene scene = new Scene(root, Color.TRANSPARENT);
scene.getRoot().setStyle("-fx-background-color: transparent");
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setAlwaysOnTop(true);
}
public static void main(String[] args) {
launch(args);
}
}
I want to render this overlay on the screen whenever I receive the POST request with the specified params
I tried using javafx.application.Application.launch(RenderCoordinateOverlay.class); in the receiveCoordinates() function
I expected the overlay to render the text the moment I sent the POST request
However, when I sent the POST request, only a completely transparent window was rendered with this error in the console:
2023-01-27T15:01:27.384+05:30 WARN 13060 --- [JavaFX-Launcher] javafx: Unsupported JavaFX configuration: classes were loaded from 'unnamed module #1ec4c0e8'
The SpringBoot application is running on my PC with a display and I expect the UI to be displayed on the PC.
I use Postman to send the post.
I am learning Spring Boot, and am working with Spring WebFlux, and reactive Mongo DB. My controllers are working fine, but my tests are failing on null pointer exception.
My build.gradle is:
plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'guru.springframework'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'junit:junit:4.12'
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
//testCompile group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '3.0.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
test {
useJUnitPlatform()
}
My Controller is:
package guru.springframework.spring5webfluxrest.controllers;
import guru.springframework.spring5webfluxrest.domain.Category;
import guru.springframework.spring5webfluxrest.repositories.CategoryRepository;
import org.reactivestreams.Publisher;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.concurrent.Flow;
#RestController
public class CategoryController {
private final CategoryRepository categoryRepository;
public CategoryController(CategoryRepository categoryRepository) {
this.categoryRepository = categoryRepository;
}
#GetMapping("/api/v1/categories")
public Flux<Category> list(){
return categoryRepository.findAll();
}
#GetMapping("/api/v1/categories/{id}")
public Mono<Category> getById(#PathVariable String id){
return categoryRepository.findById(id);
}
#ResponseStatus(HttpStatus.CREATED)
#PostMapping("/api/v1/categories")
public Mono<Void> create(#RequestBody Publisher<Category> categoryStream){
return categoryRepository.saveAll(categoryStream).then();
}
#PutMapping("/api/v1/categories/{id}")
public Mono<Category> update (#PathVariable String id, #RequestBody Category category){
category.setId(id);
return categoryRepository.save(category);
}
#PatchMapping("/api/v1/categories/{id}")
public Mono<Category> patch(#PathVariable String id, #RequestBody Category category){
Category foundCategory = categoryRepository.findById(id).block();
if(category.getDescription() != foundCategory.getDescription()){
foundCategory.setDescription(category.getDescription());
return categoryRepository.save(foundCategory);
}
return Mono.just(foundCategory);
}
}
My test is:
package guru.springframework.spring5webfluxrest.controllers;
import guru.springframework.spring5webfluxrest.domain.Category;
import guru.springframework.spring5webfluxrest.repositories.CategoryRepository;
import org.junit.Before;
import org.junit.Test;
//import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import org.mockito.Mockito;
import org.reactivestreams.Publisher;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
public class CategoryControllerTest {
WebTestClient webTestClient;
CategoryRepository categoryRepository;
CategoryController categoryController;
#Before
public void setUp() throws Exception {
categoryRepository = Mockito.mock(CategoryRepository.class);
categoryController = new CategoryController(categoryRepository);
webTestClient = WebTestClient.bindToController(categoryController).build();
}
#Test
public void list() {
given(categoryRepository.findAll())
.willReturn(Flux.just(Category.builder().description("Cat1").build(),
Category.builder().description("Cat2").build()));
webTestClient.get()
.uri("/api/v1/categories/")
.exchange()
.expectBodyList(Category.class)
.hasSize(2);
}
#Test
public void getById() {
given(categoryRepository.findById("someid"))
.willReturn(Mono.just(Category.builder().description("Cat").build()));
webTestClient.get()
.uri("/api/v1/categories/someid")
.exchange()
.expectBody(Category.class);
}
#Test
public void create() {
given(categoryRepository.saveAll(any(Publisher.class)))
.willReturn(Flux.just(Category.builder().description("descrp").build()));
Mono<Category> catToSaveMono = Mono.just(Category.builder().description("Some Cat").build());
webTestClient.post()
.uri("/api/v1/categories")
.body(catToSaveMono, Category.class)
.exchange()
.expectStatus()
.isCreated();
}
#Test
public void update() {
given(categoryRepository.save(any(Category.class)))
.willReturn(Mono.just(Category.builder().build()));
Mono<Category> catToUpdateMono = Mono.just(Category.builder().description("Some Cat").build());
webTestClient.put()
.uri("/api/v1/categories/asdfjkl")
.body(catToUpdateMono, Category.class)
.exchange()
.expectStatus()
.isOk();
}
#Test
public void testPatchNoChanges() {
given(categoryRepository.findById(anyString()))
.willReturn(Mono.just(Category.builder().build()));
given(categoryRepository.save(any(Category.class)))
.willReturn(Mono.just(Category.builder().build()));
Mono<Category> catToUpdateMono = Mono.just(Category.builder().build());
webTestClient.patch()
.uri("/api/v1/categories/asdfasdf")
.body(catToUpdateMono, Category.class)
.exchange()
.expectStatus()
.isOk();
verify(categoryRepository, never()).save(any());
}
}
Any help would be greatly appreciated.
Your test is annotated with the JUnit4's #Test annotation but you are trying to run it with JUnit5. JUnit5 cannot see it.
Uncomment the org.junit.jupiter.api.Test import and remove import org.junit.Test (CategoryControllerTest).
Remove implementation 'junit:junit:4.12' from the build.gradle as well.
I start learning Spring and in the tutorial from which I learn the lecturer uses the method: startAndAwait, which was in the reactor.ipc.netty.http.server.HttpServer package. Now there is no method, and the package is reactor.netty.http.server.HttpServer.
I would like to learn a solution based on the latest package, therefore my question is what will be the current equivalent of the following code:
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.ipc.netty.http.server.HttpServer;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
public class HelloServerApplication {
public static void main(String[] args)
{
RouterFunction route = route( GET("/"),
request -> ServerResponse.ok().body(fromObject("Hello")));
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
HttpServer server = HttpServer.create("localhost",8080);
server.startAndAwait(new ReactorHttpHandler(httpHandler));
}
}
I was looking for a solution, but my knowledge is so low that I can not cope alone with this problem. So far I wrote I changed the code to the place "server.startAndAwait" still can not replace this method:
package pl.javasurvival.helloServer;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
public class HelloServerApplication {
public static void main(String[] args)
{
RouterFunction route = route( GET("/"),
request -> ServerResponse.ok().body(fromObject("Hello")));
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
HttpServer server = HttpServer
.create()
.host("localhost")
.port(8080);
//what is a new method which is equals to startAndAwait
}
}
PS: I forgot to add that I use gradle. This is the build.gradle file:
plugins {
id 'org.springframework.boot' version '2.2.0.M4'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'pl.javasurvival'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux:2.2.0.M4'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
exclude group: 'junit', module: 'junit'
}
testImplementation 'io.projectreactor:reactor-test'
}
test {
useJUnitPlatform()
}
it has been a while, but I've found this question 1 hour ago and now I have solution, so it could be helpful for others.
Without importing old version of reactor.netty, you could try this (scanner is added only for waiting for action)
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;
import java.util.Scanner;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
public class HelloServerApplication {
public static void main(String[] args) {
RouterFunction route = route(GET("/"),
request -> ServerResponse.ok().body(fromObject("Hello")));
var httpHandler = RouterFunctions.toHttpHandler(route);
var adapter = new ReactorHttpHandlerAdapter(httpHandler);
var server = HttpServer.create().host("localhost").port(8080).handle(adapter).bindNow();
System.out.println("press enter");
Scanner sc = new Scanner(System.in);
sc.next();
server.disposeNow();
}
}
You can use the method block, as in:
DisposableServer server =
HttpServer.create()
.bindNow();
server.onDispose()
.block();
Read more in the Reactor Netty docs.
I am supposed to simply send a get-request to an endpoint and retrieve the data, and had success with post-request version of this code. However, it doesn't seem to work for GET. I have a simple model which is like this
public class Brand {
private String id;
private String name;
public Brand(String id, String name) {
this.id = id;
this.name = name;
}}
And my repository
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.http.*;
import java.util.List;
public interface Service {
#Headers({ "Accept: application/json" })
#GET("/brands")
Call<List<Brand>> getBrandList();
#Headers("Content-Type:application/json")
#POST("/login/email")
Call<ResponseBody> login(#Body LoginInfo loginInfo);
}
And finally this is where I try to run
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import java.io.IOException;
import java.util.List;
public class BrandRepoImp {
private static final String apiUrl = "http://example.com/grc/main/";
public static void main(String... args) throws IOException {
BrandRepoImp app=new BrandRepoImp();
app.getBrandList();
}
public void getBrandList() throws IOException {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(apiUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
Service resource = retrofit.create(Service.class);
Call<List<Brand>> brands = resource.getBrandList();
System.out.println(brands.execute().body());
}
}
It returns this error
Exception in thread "main" java.lang.NoSuchMethodError: okio.BufferedSource.rangeEquals(JLokio/ByteString;)Z
at okhttp3.internal.Util.bomAwareCharset(Util.java:431)
at okhttp3.ResponseBody$BomAwareReader.read(ResponseBody.java:249)
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1295)
at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1333)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:549)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:74)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:119)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:218)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
at com.retrofitexample.demo.login.BrandRepoImp.getBrandList(BrandRepoImp.java:27)
at com.retrofitexample.demo.login.BrandRepoImp.main(BrandRepoImp.java:17)
Process finished with exit code 1
I have configured all properties, but my app still loads without spring security as if it does not exist... Please help me, what I am doing wrong.
Here I get my rooms without auth with postman:
Here below are my classes:
SecurityConfiguration:
package com.vidaflo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
#Configuration
#EnableWebSecurity
#ComponentScan("com.vidaflo")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("ADMIN");
auth.inMemoryAuthentication().withUser("tom").password("abc123").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/room/**").hasRole("ADMIN")
.and()
.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
SecurityInitializer:
package com.vidaflo.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
WebConfiguration:
package com.vidaflo.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.vidaflo.controllers")
public class WebConfiguration extends WebMvcConfigurationSupport {
}
Tomcat embedded:
package com.vidaflo.server;
import com.vidaflo.config.ApplicationConfiguration;
import com.vidaflo.config.DatabaseConfiguration;
import com.vidaflo.config.SecurityConfiguration;
import com.vidaflo.config.WebConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
#Slf4j
public class Application {
private static final String APPLICATION_PROPERTIES = System.getProperty("app.properties");
private static final int DEFAULT_PORT = 8080;
private static final String DEFAULT_CONTEXT_PATH = "/app";
private AppProperties appProperties;
private AnnotationConfigWebApplicationContext ctx;
public static void main(String[] args) throws LifecycleException {
Application app = new Application(APPLICATION_PROPERTIES);
Server server = new TomcatServer(new Tomcat());
app.run(server);
}
public Application(String fieldName) {
loadProperties(fieldName);
}
public void run(Server server) {
initApplicationContext();
server.run(getConfig());
}
private void loadProperties(String fieldName) {
appProperties = new AppProperties();
appProperties.load(fieldName);
}
private void initApplicationContext() {
log.info("Initialize application context...");
ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SecurityConfiguration.class);
ctx.register(ApplicationConfiguration.class);
ctx.register(WebConfiguration.class);
ctx.register(DatabaseConfiguration.class);
ctx.getEnvironment()
.getPropertySources()
.addLast(new PropertiesPropertySource("applicationEnvironment", appProperties.getProperties()));
}
private ServerConfig getConfig() {
ServerConfig serverConfig = new ServerConfig();
serverConfig.setPort(appProperties.getPort(DEFAULT_PORT));
serverConfig.setContextPath(appProperties.getContextPath(DEFAULT_CONTEXT_PATH));
serverConfig.setServlet(getServlet());
return serverConfig;
}
private DispatcherServlet getServlet() {
return new DispatcherServlet(ctx);
}
}
Rest controller:
package com.vidaflo.controllers;
import com.vidaflo.dto.RoomDto;
import com.vidaflo.model.location.Room;
import com.vidaflo.repositories.LocationRepository;
import com.vidaflo.services.RoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
#RestController
public class RoomController {
#Autowired
private RoomService roomService;
#Autowired
private LocationRepository locationService;
#PostMapping("/room/save")
public String save(#RequestParam(name = "name") String name,
#RequestParam(name = "location_id") Long locationId) {
roomService.save(name, locationService.findOne(locationId));
return "room added";
}
#GetMapping("/room/all")
public List<RoomDto> findAll() {
return roomService.findAll().stream()
.map(this::toDto)
.collect(Collectors.toList());
}
private RoomDto toDto(Room room) {
return RoomDto.builder()
.id(room.getId())
.name(room.getName())
.build();
}
}
Please tell me if I should add additional details. I rly need help and I can't understand what I'm doing wrong.
Found an answer, we should manually add filter for spring security in tomcat embedded config like this:
FilterDef filterDef = new FilterDef();
filterDef.setFilterName("springSecurityFilterChain");
filterDef.setFilterClass("org.springframework.web.filter.DelegatingFilterProxy");
container.addFilterDef(filterDef);
FilterMap filterMapping = new FilterMap();
filterMapping.setFilterName("springSecurityFilterChain");
filterMapping.addURLPattern("/*");
container.addFilterMap(filterMapping);
Try to change role "ADMIN" "USER" to "ROLE_ADMIN" "ROLE_USER" in configureGlobalSecurity method and in the enum "Roles", but in configure method don't change.