Java 从数据库中动态检索控制器中特定方法的Spring Boot CORS配置
我正在尝试使用以下命令在控制器级别设置CORS配置Java 从数据库中动态检索控制器中特定方法的Spring Boot CORS配置,java,spring-boot,cors,microservices,jhipster,Java,Spring Boot,Cors,Microservices,Jhipster,我正在尝试使用以下命令在控制器级别设置CORS配置 @CrossOrigin on Controller and Handler Method public class AccountController { @CrossOrigin("retreive data from DB") @RequestMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } } 我尝试过使用下面的方法,但它只
@CrossOrigin on Controller and Handler Method
public class AccountController {
@CrossOrigin("retreive data from DB")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
}
我尝试过使用下面的方法,但它只在spring启动时设置,并且只有在下次重新启动服务时才进行更改
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// CorsConfiguration config = jHipsterProperties.getCors();
CorsConfiguration config=CorsService.fetchCorsConfigFromDb;
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/management/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
}
return new CorsFilter(source);
}
fetchCorsConfigFromDb
将从数据库中获取数据。DB中的任何更改只有在Spring Boot应用程序重新启动时才会反映出来
用于
CorsService.fetchCorsConfigFromDb代码>
它应该从缓存加载
然后您可以在运行时更新缓存
您应该实现CorsService.fetchCorsConfig()代码>
此方法应首先在缓存中查找任何cors配置,如果找到任何配置,请直接从缓存加载它,否则您将从db检索cors并更新缓存
创建运行时更新cors方法CorsService.updateCorsConfig()代码>,这将更新数据库中的cors,然后更新缓存
要实现此功能,您可以使用一个基本筛选器,在该筛选器中,您可以编写自定义数据库逻辑,根据某些数据库属性值将CORS头添加到请求中
您可以参考下面的示例,使用SpringDataJPA实现此功能
将DB连接属性添加到application.properties文件
应用程序属性
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=postgres
spring.datasource.password=root
创建具有以下属性的实体以将URL保存在数据库中
Cors.java
@Entity
@Getter
@Setter
public class Cors {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String url;
private boolean isAllowed;
}
public interface CorsRepository extends JpaRepository<Cors,Long> {
Optional<Cors> findByUrl(String url);
}
@Component
public class CorsFilter implements Filter {
@Autowired
CorsRepository corsRepository;
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String url = request.getRequestURI().toString();
System.out.println(url);
Optional<Cors> cors = corsRepository.findByUrl(url);
if(cors.isPresent() && cors.get().isAllowed()){
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
}
chain.doFilter(req, res);
}
@Override
public void destroy() { }
}
@RestController
public class CorsTesterController {
@GetMapping("/api/v1/test")
String getResponse(){
return "test response";
}
}
并且在存储库中添加了一个findByUrl
方法,根据URL从数据库中获取值
CorsRepository.java
@Entity
@Getter
@Setter
public class Cors {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String url;
private boolean isAllowed;
}
public interface CorsRepository extends JpaRepository<Cors,Long> {
Optional<Cors> findByUrl(String url);
}
@Component
public class CorsFilter implements Filter {
@Autowired
CorsRepository corsRepository;
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String url = request.getRequestURI().toString();
System.out.println(url);
Optional<Cors> cors = corsRepository.findByUrl(url);
if(cors.isPresent() && cors.get().isAllowed()){
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
}
chain.doFilter(req, res);
}
@Override
public void destroy() { }
}
@RestController
public class CorsTesterController {
@GetMapping("/api/v1/test")
String getResponse(){
return "test response";
}
}
您可以创建如下示例控制器:
CorsTesterController.java
@Entity
@Getter
@Setter
public class Cors {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String url;
private boolean isAllowed;
}
public interface CorsRepository extends JpaRepository<Cors,Long> {
Optional<Cors> findByUrl(String url);
}
@Component
public class CorsFilter implements Filter {
@Autowired
CorsRepository corsRepository;
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String url = request.getRequestURI().toString();
System.out.println(url);
Optional<Cors> cors = corsRepository.findByUrl(url);
if(cors.isPresent() && cors.get().isAllowed()){
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
}
chain.doFilter(req, res);
}
@Override
public void destroy() { }
}
@RestController
public class CorsTesterController {
@GetMapping("/api/v1/test")
String getResponse(){
return "test response";
}
}
并向DB插入值以允许/不允许url测试此示例代码
testdb=# select * from cors;
id | is_allowed | url
----+------------+-----------------
1 | f | /api/v1/block
2 | t | /api/v1/allowed
谢谢如果你觉得这个问题相关。请把问题投上一票太好了!!好主意。如果你觉得这个问题相关。请向上投票@Ajit Soman为什么不在ApplicationCOntext上使用getBean()而不是自动连接CorsRepository?您可以查看以下链接:@GaëlMarziou,您是对的<代码>@Autowiring
将在带有@组件的过滤器中工作。注释已删除。我已经根据评论更新了答案