小编Mat*_*nkt的帖子

如何使用Spring Data Rest公开resourceId

我曾经暴露了在实体中用@Id注释的主键.ID字段只在资源路径上可见,但在JSON主体上不可见.

spring hypermedia spring-data-rest spring-hateoas

12
推荐指数
1
解决办法
5176
查看次数

Kotlin数据类和带有容器元素约束的bean验证

使用Bean Validation 2.0,还可以对容器元素设置约束.

我无法使用Kotlin数据类:

data class Some(val someMap: Map<String, @Length(max = 255) String>)
Run Code Online (Sandbox Code Playgroud)

这没有任何效果.有任何想法吗?

我创建了一个包含示例项目的存储库来重现案例:https://github.com/mduesterhoeft/bean-validation-container-constraints

spring-mvc bean-validation kotlin

12
推荐指数
2
解决办法
775
查看次数

Spring Cloud Config Server环境变量的优先级

在使用spring cloud配置服务器时,我对环境变量的优先级有疑问

在我的服务中,我有一个application.yml包含此内容的本地属性文件

foo:
  bar: "some"
  buz: "some"
  joe: "some"
Run Code Online (Sandbox Code Playgroud)

该服务还连接到配置服务器,配置存储库包含一个文件testservice-api.yml(其中testservice-api是服务的spring应用程序名称).该文件的内容是:

foo:
  bar: "some-specific"
Run Code Online (Sandbox Code Playgroud)

因此,使用此设置,运行时的配置将导致:

{
    "foo.bar": "some-specific",
    "foo.buz": "some",
    "foo.joe": "some"
}
Run Code Online (Sandbox Code Playgroud)

现在我尝试覆盖foo.barfoo.joe使用环境变量.

所以我用这个命令启动服务:

FOO_BAR=some-env FOO_JOE=some-env gradle bootRun

从我在spring boot文档这一部分中读到的内容,环境变量应优先于配置文件 - spring cloud配置文档也没有说明不同 - 所以我希望结果如下:

{
    "foo.bar": "some-env",
    "foo.buz": "some",
    "foo.joe": "some-env"
}
Run Code Online (Sandbox Code Playgroud)

但相反,我得到:

{
    "foo.bar": "some-specific",
    "foo.buz": "some",
    "foo.joe": "some-env"
}
Run Code Online (Sandbox Code Playgroud)

因此,只有来自jar内部的本地配置文件的配置被环境变量覆盖 - 来自config repo的属性似乎优先于环境变量.

这是可以解释的 - 或者这是一个错误?这一个有什么提示吗?

请在此处找到示例代码:

https://github.com/mduesterhoeft/configserver-test …

java spring spring-boot spring-cloud spring-cloud-config

9
推荐指数
1
解决办法
5321
查看次数

Spring RestTemplate将流响应转换为另一个请求

我正在尝试使用spring将文件下载的结果直接传输到另一个帖子 RestTemplate

我目前的做法如下:

   ResponseEntity<InputStreamResource> downloadResponse = restTemplate.getForEntity(fileToDownloadUri, InputStreamResource.class);

   InputStreamResource imageInputStreamResource = downloadResponse.getBody();

   ResponseEntity<String> response = restTemplate.exchange(storageUri, POST, new HttpEntity<>(imageInputStreamResource), String.class);
Run Code Online (Sandbox Code Playgroud)

但是,运行上面的代码时出现以下异常:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://host:port/path/some.jpg": stream is closed; nested exception is java.io.IOException: stream is closed

    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:6
...
Caused by: java.io.IOException: stream is closed
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3348)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3373)
Run Code Online (Sandbox Code Playgroud)

似乎响应总是作为处理的最后一步关闭.响应时,HttpURLConnection关闭,流不再可处理.

我希望能够实现这个场景,而不必完全存放文件在内存中或将其写入文件(如描述在这里).

任何提示都非常感谢.

java spring spring-mvc

7
推荐指数
2
解决办法
1万
查看次数

Spring Security Oauth - OAuth2Exceptions 的自定义格式

spring security oauth 的错误格式符合 OAuth 规范,看起来像这样。

{
  "error":"insufficient_scope",
  "error_description":"Insufficient scope for this resource",
  "scope":"do.something"
}
Run Code Online (Sandbox Code Playgroud)

特别是在资源服务器上,我发现为身份验证问题获取不同的错误格式有点奇怪。所以我想改变这个异常的呈现方式。

文件说:

授权服务器中的错误处理使用标准的 Spring MVC 特性,即 @ExceptionHandler 方法

所以我尝试了这样的事情来自定义错误的格式:

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyErrorHandler {

    @ExceptionHandler(value = {InsufficientScopeException.class})
    ResponseEntity<MyErrorRepresentation> handle(RuntimeException ex, HttpServletRequest request) {
        return errorResponse(HttpStatus.FORBIDDEN,
                MyErrorRepresentation.builder()
                        .errorId("insufficient.scope")
                        .build(),
                request);
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

查看代码,所有的错误渲染似乎都是在DefaultWebResponseExceptionTranslator#handleOAuth2Exception. 但是实现自定义WebResponseExceptionTranslator不允许更改格式。

任何提示?

spring spring-security spring-security-oauth2

6
推荐指数
2
解决办法
6709
查看次数

带有 kotlin 的 gradle 插件 - 设置布尔扩展属性

我正在尝试将 gradle 插件从 groovy 迁移到 kotlin。我有一个布尔值Property,我想在我的插件扩展中将其初始化为 false:

open class MyPluginExtension(project: Project) {

    val myBooleanProperty: Property<Boolean> = project.objects.property(Boolean::class.java)

    init {
        myBooleanProperty.set(false)
    }
}
Run Code Online (Sandbox Code Playgroud)

这失败了

java.lang.IllegalArgumentException: Cannot set the value of a property of type boolean using an instance of type java.lang.Boolean.
Run Code Online (Sandbox Code Playgroud)

异常被抛出org.gradle.api.internal.provider.DefaultPropertyState#set(T)

对此有什么想法吗?

gradle kotlin gradle-plugin

6
推荐指数
1
解决办法
1114
查看次数

具有资源所有者密码凭证和JWT的Spring Security OAuth2客户端SSO

我正在尝试使用带有JsonWebToken的spring security oauth2来实现身份验证。

对于外部应用程序,我计划使用“授权代码授予流程”,但是对于可信的前端,我们希望使用“资源所有者密码凭证授予流程”。

JWT应该保存在UI服务器的会话中-而且UI服务器还保存客户端凭据-它们不会暴露给客户端。因此,用户使用UI服务器登录。服务器使用身份验证服务器的令牌终结点来请求JsonWebToken,将其转换为OAuth2Authentication并将其存储在SecuritContextHolder中。

我使用自定义控制器登录方法实现了这一点。但我希望能够使用@EnableOauth2Sso并避免自定义实现。我看到了一些如何使用“授权代码授予流程”执行此操作的示例-例如,这一个https://spring.io/guides/tutorials/spring-security-and-angular-js/-但与文档无关和“资源所有者密码凭证授予流”的教程。

有什么提示吗?

spring-security jwt spring-security-oauth2

5
推荐指数
0
解决办法
542
查看次数

spring-amqp 事务语义

我目前正在测试一个相当简单的示例,涉及与 Spring amqp 的数据库事务相关的消息传递事务。

用例如下:

  • 收到消息
  • 一条消息已发送
  • 数据库已更新

    @Transactional
    public void handleMessage(EventPayload event) {
        MyEntity entity = new MyEntity();
        entity.setName(event.getName());
    
        rabbitTemplate.convertAndSend("myExchange", "payload.create", payload);
    
        MyEntity savedEntity = entityRepository.save(entity);
    }
    
    Run Code Online (Sandbox Code Playgroud)

如果数据库操作期间发生故障,预期的行为是接收到的消息回滚到总线 (DefaultRequeueRejected = false) 并进入死信队列。发送的消息也应该回滚。

我可以通过以下配置来实现此目的:

@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setMessageConverter(messageConverter);
    rabbitTemplate.setChannelTransacted(true);
    return rabbitTemplate;
}

@Bean
    SimpleMessageListenerContainer subscriberListenerContainer(ConnectionFactory connectionFactory,
                                                              MessageListenerAdapter listenerAdapter,
                                                              PlatformTransactionManager transactionManager) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(SUBSCRIBER_QUEUE_NAME);
        container.setMessageListener(listenerAdapter);
        container.setChannelTransacted(true);
        container.setTransactionManager(transactionManager);
        container.setDefaultRequeueRejected(false);
        return container;
    }
Run Code Online (Sandbox Code Playgroud)

所以这工作得很好 - 我不明白的是,如果我没有在 上设置事务管理器,观察到的行为是完全相同的SimpleMessageListenerContainer …

java spring rabbitmq spring-amqp

5
推荐指数
1
解决办法
4179
查看次数

Spring AMQP StatefulRetryOperationsInterceptor未使用

我正在尝试配置spring amqp只重试一次消息定义的次数.目前,例如由于a而失败的消息DataIntegrityViolationException 被无限期地重新传递.

根据这里的文档,我提出了以下配置

@Bean
    public StatefulRetryOperationsInterceptor statefulRetryOperationsInterceptor() {
        return RetryInterceptorBuilder.stateful()
                .backOffOptions(1000, 2.0, 10000) // initialInterval, multiplier, maxInterval
                .maxAttempts(3)
                .messageKeyGenerator(message -> UUID.randomUUID().toString())
                .build();
    } 
Run Code Online (Sandbox Code Playgroud)

这似乎没有应用 - 消息仍然无限期地尝试.

感觉就像我在这里遗漏了一些东西.

以下是关于AMQP的剩余配置:

@Bean
    Queue testEventSubscriberQueue() {
        final boolean durable = true;
        return new Queue("testEventSubscriberQueue", durable);
    }

    @Bean
    Binding binding(TopicExchange topicExchange) {
        return BindingBuilder.bind(testEventSubscriberQueue()).to(topicExchange).with("payload.event-create");
    }

    @Bean
    SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(testEventSubscriberQueue().getName());
        container.setMessageListener(listenerAdapter);
        container.setChannelTransacted(true);
        return container;
    }


    @Bean
    MessageListenerAdapter listenerAdapter(MessageConverter messageConverter, SubscriberHandler …
Run Code Online (Sandbox Code Playgroud)

java spring rabbitmq spring-amqp spring-retry

4
推荐指数
1
解决办法
1119
查看次数

断言错误:JUnit测试中没有JSON Path的值

我已经编写了一个测试并且之前成功但现在我得到一个AssertionError:没有JSON Path的值.

@Test
public void testCreate() throws Exception {
    Wine wine = new Wine();
    wine.setName("Bordeaux");
    wine.setCost(BigDecimal.valueOf(10.55));

    new Expectations() {
        {
            wineService.create((WineDTO) any);
            result = wine;
        }
    };

    MockMultipartFile jsonFile = new MockMultipartFile("form", "", "application/json", "{\"name\":\"Bordeaux\", \"cost\": \"10.55\"}".getBytes());
    this.webClient.perform(MockMvcRequestBuilders.fileUpload("/wine").file(jsonFile))
            .andExpect(MockMvcResultMatchers.status().is(200))
            .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("Bordeaux"))
            .andExpect(MockMvcResultMatchers.jsonPath("$.cost").value(10.55));
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

java.lang.AssertionError: No value for JSON path: $.name, exception: No results path for $['name']
Run Code Online (Sandbox Code Playgroud)

我不明白它没有得到什么或者缺少什么.

java junit json spring-mvc-test

4
推荐指数
2
解决办法
1万
查看次数