我在一个简单的 vaadin 应用程序中设置了一个 Rest 控制器,它有一个非常基本的 Post 类型的请求映射,当点击 endint 时,它应该在日志中打印一些文本。然而,当从邮递员到达端点时,我收到 200 ok,并且在正文中收到一个自动的 html 页面。
我在其他项目中设置过Rest Controller,以前从未遇到过这个问题。我知道我错过了一些简单的事情(我希望!),但我就是找不到问题所在。
完整的源代码在这里:https://github.com/nonWhistle/tkhmm-home.git
任何对此的建议将不胜感激。
下面是 Restcontroller 和 POM 文件,应用程序的入口点用 @SpringBootApplication 注释,我认为 RestController 正在组件扫描中被拾取,因为构造函数打印“Created”。
我怀疑这可能是我的安全配置方式的问题,因此我已将其包含在我的 SecurityConfiguration 类中。
休息控制器
package com.tkhmm.application.rest;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.logging.Logger;
@RestController
@RequestMapping(value = "/tkhmm/cv")
public class CvViewController {
private static final Logger log = Logger.getLogger(CvViewController.class.getSimpleName());
protected static final String API_KEY_HEADER_NAME = "api-key";
public CvViewController() {
log.info("Created");
}
@PostMapping("/labeltext/{message}")
@ResponseStatus(HttpStatus.OK)
public void updateLabelTextInCvView(@PathVariable("message") String message,
@RequestHeader(name = API_KEY_HEADER_NAME) String apiKey) {
log.info("HERE -> " + message);
log.info("HERE -> " + apiKey);
}
@PostMapping("/test")
public void test() {
log.info("HERE");
}
}
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>
<!-- Project from https://start.vaadin.com/project/5da11fe1-c5a6-48ba-b4e2-dd8ab29c346d -->
<groupId>com.tkhmm.application</groupId>
<artifactId>tkhmm</artifactId>
<name>tkhmm</name>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<java.version>11</java.version>
<vaadin.version>23.3.2</vaadin.version>
<!-- this parameter is needed as spring-boot bom overwrites it -->
<selenium.version>4.5.3</selenium.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
</parent>
<repositories>
<!-- The order of definitions matters. Explicitly defining central here to make sure it has the highest priority. -->
<!-- Main Maven repository -->
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>vaadin-prereleases</id>
<url>
https://maven.vaadin.com/vaadin-prereleases/
</url>
</repository>
<!-- Repository used by many Vaadin add-ons -->
<repository>
<id>Vaadin Directory</id>
<url>https://maven.vaadin.com/vaadin-addons</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!-- The order of definitions matters. Explicitly defining central here to make sure it has the highest priority. -->
<pluginRepository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>vaadin-prereleases</id>
<url>
https://maven.vaadin.com/vaadin-prereleases/
</url>
</pluginRepository>
</pluginRepositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<!-- Replace artifactId with vaadin-core to use only free components -->
<artifactId>vaadin</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-testbench</artifactId>
<scope>test</scope>
</dependency>
<!-- Include JUnit 4 support for TestBench and others -->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
</dependencies>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- Clean build and startup time for Vaadin apps sometimes may exceed
the default Spring Boot's 30sec timeout. -->
<configuration>
<jvmArguments>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5122</jvmArguments>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
</configuration>
</plugin>
<!--
Take care of synchronizing java dependencies and imports in
package.json and main.js files.
It also creates webpack.config.js if not exists yet.
-->
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>tkhmm-home</finalName>
</build>
<profiles>
<profile>
<!-- Production mode is activated using -Pproduction -->
<id>production</id>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<goals>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<configuration>
<productionMode>true</productionMode>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>it</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>start-spring-boot</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-spring-boot</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Runs the integration tests (*IT) after the server is started -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<trimStackTrace>false</trimStackTrace>
<enableAssertions>true</enableAssertions>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
安全配置
package com.tkhmm.application.security;
import com.tkhmm.application.views.login.LoginView;
import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll();
super.configure(http);
setLoginView(http, LoginView.class);
}
}
如果 VaadinServelt 映射到根映射(默认),您必须通过在
vaadin.exclude-urls
文件中设置 application.properties
来告诉它忽略您的控制器路径,例如
vaadin.exclude-urls=/tkhmm/**
这是文档页面的链接 https://vaadin.com/docs/latest/integrations/spring/configuration/#prevent-handling-of-specific-urls
此外,您可能应该禁用控制器的 CSRF 并在安全配置中对其进行授权
protected void configure(HttpSecurity http) throws Exception {
...
http.authorizeRequests(auth -> auth.mvcMatchers("/tkhmm/**").permitAll());
http.csrf().ignoringAntMatchers("/tkhmm/**");
...
super.configure(http);
...
}
要调试正在发生的情况,您还可以在 application.properties 中将 spring security 记录器设置为 DEBUG 级别
logging.level.org.springframework.security=DEBUG