Some nice "greater-than sign" code in Tomcat. Needs a healthy dose of (>>=).
查看 the AuthenticatorBase.java class from Apache Tomcat 时:
/**
* Enforce the security restrictions in the web application deployment
* descriptor of our associated Context.
*
* @param request Request to be processed
* @param response Response to be processed
*
* @exception IOException if an input/output error occurs
* @exception ServletException if thrown by a processing element
*/
@Override
public void invoke(Request request, Response response)
throws IOException, ServletException {
if (log.isDebugEnabled())
log.debug("Security checking request " +
request.getMethod() + " " + request.getRequestURI());
LoginConfig config = this.context.getLoginConfig();
// Have we got a cached authenticated Principal to record?
if (cache) {
Principal principal = request.getUserPrincipal();
if (principal == null) {
Session session = request.getSessionInternal(false);
if (session != null) {
principal = session.getPrincipal();
if (principal != null) {
if (log.isDebugEnabled())
log.debug("We have cached auth type " +
session.getAuthType() +
" for principal " +
session.getPrincipal());
request.setAuthType(session.getAuthType());
request.setUserPrincipal(principal);
}
}
}
}
我必须承认,我不知道如何应用它。我知道可能有一种方法可以将 if 树重构为单子(monad)绑定(bind),但我不知道该怎么做。
假设:
- 这与语言无关,而是与逻辑构造有关。您可以用 Haskell、Scala 或 Clojure 来表示这个 if 树,它仍然表示相同的 if 逻辑。
我的问题是:如何使用 Monadic Bind 简化此 Apache Tomcat 代码?
最佳答案
好吧,这里你有副作用(request.set...
),当你没有副作用时,bind 更有用。使用 ifPresent
就足够了:
Optional.ofNullable(principal).ifPresent(principal ->
Optional.ofNullable(request.getSessionInternal(false)).ifPresent(session ->
Optional.ofNullable(session.getPrincipal).ifPresent(principal -> {
if (log.isDebugEnabled())
log.debug(...);
request.setAuthType(session.getAuthType());
request.setUserPrincipal(principal);
})));
这看起来可能不像是一场胜利;重复,但如果 request.getSessionInternal
和 session.getPrincipal
已返回,则不需要 Optional.ofNullable(...)
Optional
。
您可以编写一个类似于 Optional.ofNullable(...).ifPresent
的方法:
public static <T> void ifNotNull(T value, Consumer<? super T> consumer) {
if (value != null) { consumer.accept(value); }
}
ifNotNull(principal, principal ->
ifNotNull(request.getSessionInternal(false), session ->
ifNotNull(session.getPrincipal, principal -> {
if (log.isDebugEnabled())
log.debug(...);
request.setAuthType(session.getAuthType());
request.setUserPrincipal(principal);
})));
(注意:不确定我是否准确记得 Java 语法,我已经有一段时间没有使用它了。)
关于java - 如何使用 Monadic Bind 简化此 Apache Tomcat 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34450149/