【问题标题】:Logger, convert from @Inject to producer记录器,从@Inject 转换为生产者
【发布时间】:2014-01-31 08:17:51
【问题描述】:

我在实现像示例 Simple CRUD Web Application with JSF 2.1, PrimeFaces 3.5, EJB 3.1, JPA (ORM) / EclipseLink, JAAS , MySQL 这样的登录界面时遇到问题 在 TomEE 的邮件列表中,有人告诉我,我正在使用的 LoginController.java 试图注入 Logger,但 Logger 注入不是由 CDI 管理的。有人告诉我改用生产者。不知道是什么,我在网上搜索,我找到了this example 但是我还是不太适应,所以请解释一下我必须修改什么来实现logger的生产者。

LoginController.java

package controller;

import util.DateUtility;

import java.io.IOException;
import java.io.Serializable;
import java.security.Principal;
import java.util.logging.Level;
import java.util.logging.Logger;


import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * Login Controller class allows only authenticated users to log in to the web
 * application.
 *
 * @author Emre Simtay <emre@simtay.com>
 */
@Named
@SessionScoped

public class LoginController implements Serializable {

    @Inject
    private transient Logger logger;
    private String username;
    private String password;

    /**
     * Creates a new instance of LoginController
     */
    public LoginController() {
        System.out.println("test");
    }

    //  Getters and Setters
    /**
     * @return username
     */
    public String getUsername() {
        return username;
    }

    /**
     *
     * @param username
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     *
     * @return password
     */
    public String getPassword() {
        return password;
    }

    /**
     *
     * @param password
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * Listen for button clicks on the #{loginController.login} action,
     * validates the username and password entered by the user and navigates to
     * the appropriate page.
     *
     * @param actionEvent
     */
    public void login(ActionEvent actionEvent) {
        System.out.println("CONSOLE PRINT TEST");

        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            String navigateString = "";
            // Checks if username and password are valid if not throws a ServletException
            request.login(username, password);
            // gets the user principle and navigates to the appropriate page
            Principal principal = request.getUserPrincipal();
            if (request.isUserInRole("Administrator")) {
                navigateString = "/admin/AdminHome.xhtml";
            } else if (request.isUserInRole("Manager")) {
                navigateString = "/manager/ManagerHome.xhtml";
            } else if (request.isUserInRole("User")) {
                navigateString = "/user/UserHome.xhtml";
            }
            try {
                logger.log(Level.INFO, "User ({0}) loging in #" + DateUtility.getCurrentDateTime(), request.getUserPrincipal().getName());
                context.getExternalContext().redirect(request.getContextPath() + navigateString);
            } catch (IOException ex) {
                logger.log(Level.SEVERE, "IOException, Login Controller" + "Username : " + principal.getName(), ex);
                context.addMessage(null, new FacesMessage("Error!", "Exception occured"));
            }
        } catch (ServletException e) {
            logger.log(Level.SEVERE, e.toString());
            context.addMessage(null, new FacesMessage("Error!", "The username or password you provided does not match our records."));
        }
    }

    /**
     * Listen for logout button clicks on the #{loginController.logout} action
     * and navigates to login screen.
     */
    public void logout() {

        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        logger.log(Level.INFO, "User ({0}) loging out #" + DateUtility.getCurrentDateTime(), request.getUserPrincipal().getName());
        if (session != null) {
            session.invalidate();
        }
        FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), null, "/Login.xhtml?faces-redirect=true");
    }
}

【问题讨论】:

    标签: jsf jakarta-ee cdi jaas apache-tomee


    【解决方案1】:

    当您使用@Inject 时,CDI 会尝试为您创建请求类型的实例。最简单的解决方案:它调用默认构造函数并返回该实例。

    java.util.logging.Logger 的问题:它没有可见的默认构造函数。因此,您必须告诉 CDI 如何通过将 Producer 添加到您的类路径来满足依赖关系。尽管使用 @JohnAment 建议的焊接记录器也是我的首选解决方案,但鉴于您目前的知识水平,如果您从添加自己的生产者开始,它可能对您来说是最好的。

    所以在你的控制器旁边,创建一个新的类(添加包,导入,......你自己)

    public class LoggerProducer {
       @Produces
       public Logger getLogger(InjectionPoint p) {
         return Logger.getLogger(p.getClass().getCanonicalName());
       }
    }
    

    这告诉 CDI 容器:当您需要注入 java.util.logging.Logger 时,使用此方法通过获取需要该记录器引用的类的 fqn 名称来创建一个。

    这应该可以解决您的问题。一旦你有了这个想法,想想你是否真的想要/需要使用 java.util.logging 或者你是否想要切换到 slf4j。在这种情况下,请修改您的控制器导入,删除您刚刚编写的 LoggerProducer,然后将 weld-logger jar 导入到您的部署中。

    【讨论】:

    • 那么,如果 Logger 有一个公共的默认构造函数,一切都会奏效吗?我可能错了,但这仍然行不通(没有 beans.xml)
    【解决方案2】:

    它们是正确的,没有可用的标准记录器注入。您可以查看 Weld 的这个示例,了解如何注入他们的客户记录器。请随意修改它以使用 java.util.logging。

    http://grepcode.com/file/repo1.maven.org/maven2/org.jboss.weld/weld-logger/1.0.0-CR1/org/jboss/weld/log/LoggerProducer.java

    【讨论】:

    • Thx,但我更喜欢修改现有的 LoginController.java bean,因为 SimTay 网站上的整个示例非常适合我的需要,所以如果我大幅更改它,恐怕它不会起作用。
    • 是什么让你觉得你需要修改登录控制器?生产者进入一个单独的班级。
    • 完全没有使用Producer的经验让我觉得我需要修改登录控制器。你知道任何解释如何使用它的好网页吗?就我个人而言,我只是在网上找到了一些令人困惑的解释。
    • 我发现关于生产者的焊接文档非常有帮助:docs.jboss.org/weld/reference/1.0.0/en-US/html/…
    猜你喜欢
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多