我编写了一个由自定义实现的验证注释ConstraintValidator.我还想生成非常具体的ConstraintViolation对象,这些对象使用在消息插值期间验证过程中计算的值.
public class CustomValidator
implements ConstraintValidator<CustomAnnotation, ValidatedType> {
...
@Override
public boolean isValid(ValidatedType value, ConstraintValidatorContext context) {
// Figure out that the value is not valid.
// Now, I want to add a violation whose error message requires arguments.
}
}
Run Code Online (Sandbox Code Playgroud)
我的消息源中的假设错误消息:
CustomAnnotation.notValid = The supplied value {value} was not valid because {reason}.
Run Code Online (Sandbox Code Playgroud)
传递给isValid方法的上下文提供了用于构建约束违规的接口,并最终将其添加到上下文中.但是,我似乎无法弄清楚如何使用它.根据我正在使用的版本的这个文档,我可以添加bean和属性节点到违规.这些是我可以为违规定义指定的唯一附加细节,但我不明白它们如何映射到错误消息中的参数.
百万美元的问题:如何使用自定义验证器将动态参数传递给我的验证错误消息?我想使用用于构建违规的界面填写这些{value}和{reason}字段ConstraintValidatorContext.
获取消息源的实例并在自定义验证器中插入消息不是一个选项 - 无论如何都会对来自验证的消息进行插值,并且内部插值将导致某些消息被插值两次,可能会消除转义单引号或我的消息定义文件中具有特殊含义的其他字符.
我的Spring服务器上的安全上下文使用Spring Security的内置表单登录实现.目前,登录会话由servlet容器本地存储在内存中.我想用我的一个Spring Data Mongo存储库替换HttpSessions的存储和检索方式.我在Java配置中查找了其中一个用于会话管理的"插槽",但没有找到任何内容.要清楚,我正在寻找UserDetailsService的等价物,但是对于会话.
这是我的安全配置类中相关的Java配置片段:
...
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.formlogin()
.loginProcessingUrl("/authentication/login")
.successHandler(successHandler)
.usernameParameter("username")
.passwordParameter("password")
.failureUrl("/login?error")
.loginPage("/login")
.and()
.logout()
.logoutUrl("/authentication/logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.logoutSuccessUrl("/login")
.and()
...
Run Code Online (Sandbox Code Playgroud)
据我所知,我没有做任何特别奇怪的事情.它可能没有关系,但是当我说找不到正确的配置槽时,我想准确地显示我正在看的内容.
我仔细查看了SecurityContextPersistenceFilter的源代码,它似乎是Spring Security的过滤器链中的过滤器,负责检索和存储HttpSession.它代表会话检索到一个呼叫getSession()中的HttpServletRequest和会话存储,以saveContext()在注入SecurityContextRepository.
为了正确地替换默认的服务器本地会话存储机制,我看到了三种方法.
将Spring Data支持的安全上下文存储库插入持久性过滤器.然后,包装传入的请求以实现getSession()查询自定义安全上下文存储库而不是本地存储的自定义行为.然后内置的持久性过滤器将"做正确的事情".
设置ObjectPostProcessor以使用自定义SecurityContextPersistenceFilter替换默认筛选器,该自定义SecurityContextPersistenceFilter直接使用我的Spring Data存储库而不是调用getSession()或使用安全上下文存储库.我以前从未使用过对象后处理器,所以如果这不是他们的意思,请告诉我.
最后一个选项不是我正在考虑的选项,但值得一提.我认为在所有魔法之下,Spring Security真正委托servlet容器的会话存储实现.因此,将后备存储更改为Mongo的一种方法是使用类似Tomcat的Manager接口来自定义会话持久性行为.这不是我想要做的事情,因为它与Spring完全分开,我失去了通过依赖注入使用我的服务的能力,而且它完全取决于容器,因此很难随心所欲地改变.
我确信将会话存储空间化并用数据库替换它是Spring服务器的一个相当普遍的要求.通常怎么做?如果我只是错过配置选项,我很乐意看到它的位置.否则,关于采取哪条路线(以及为什么)的建议是我正在寻找的.