视图和bean一直在工作,直到我试图修复非标准名称,现在我已经打破了两者之间的连接。奇怪的是,“返回”按钮有正确的链接,但内容就是不显示,也不记录。为什么不执行Detail.get注释()?
我一直在浏览焊接文档,并试图更好地理解@Inject。似乎有一个我也不明白的生命周期问题。如果它不是生命周期,那么我甚至不能推测为什么Detail.get注释()从未在glassfish日志中显示:
INFO: MessageBean.getModel..
INFO: SingletonNNTP.returning messages..
INFO: MessageBean.getModel..
INFO: SingletonNNTP.returning messages..
INFO: MessageBean.getModel..
INFO: SingletonNNTP.returning messages..
INFO: Detail..
INFO: Detail.getId..null
INFO: Detail.getId..SETTING DEFAULT ID
INFO: Detail.onLoad..2000
INFO: Detail.getId..2000
INFO: Detail.getId..2000
INFO: Detail.setId..2000
INFO: Detail.getId..2019
INFO: ..Detail.setId 2019
INFO: Detail.back..
INFO: Detail.getId..2019
INFO: ..Detail.back 2,018
INFO: Detail.getId..2019
值2000是一个默认值,只有当id==null时才会发生,它永远不应该这样做。它应该立即引入该属性。因此,我不确定这是否是范围(我刚刚才发现CDI不支持@SessionScoped)、生命周期或其他方面的问题。也许我需要在那个变量上使用@Inject?
视图、细节。xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<f:metadata>
<f:viewParam name="id" id="id" value="#{detail.id}" />
</f:metadata>
<ui:composition template="./complexTemplate.xhtml">
<ui:define name="top">
<h:link value="back" outcome="detail" includeViewParams="true">
<f:param name="id" value="#{detail.back}"/>
</h:link>
<ui:define name="content">
<h:outputText value="#{detail.content}" rendered="false"/>
</ui:define>
<ui:define name="bottom">
bottom
</ui:define>
</ui:composition>
</body>
</html>
和背景豆:
package net.bounceme.dur.nntp;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;
import javax.mail.Message;
@Named
@ConversationScoped
public class Detail implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(Detail.class.getName());
private static final Level level = Level.INFO;
private String id = null; //should never get default value in getter
private Message message = null;
private SingletonNNTP nntp = SingletonNNTP.INSTANCE;
private String forward = null; //id + 1
private String back = null; //id - 1
private String content = null; //message.content
public Detail() {
logger.log(level, "Detail..");
}
@PostConstruct
private void onLoad() {
logger.log(level, "Detail.onLoad..{0}", getId());
}
public Message getMessage() {
logger.log(level, "Detail.getMessage..");
return message;
}
public void setMessage(Message message) {
logger.log(level, "Detail.setMessage..");
this.message = message;
}
public String getId() {
logger.log(level, "Detail.getId..{0}", id);
if (id == null) {
logger.log(level, "Detail.getId..SETTING DEFAULT ID");
id = String.valueOf(2000);
}
return id;
}
public void setId(String id) throws Exception {
logger.log(level, "Detail.setId..{0}", getId());
this.id = id;
logger.log(level, "..Detail.setId {0}", getId());
}
public String getForward() {
logger.log(level, "Detail.forward..");
int f = Integer.parseInt(getId());
f = f + 1;
logger.log(level, "..Detail.forward {0}", f);
forward = String.valueOf(f);
return forward;
}
public void setForward(String forward) {
this.forward = forward;
}
public String getBack() {
logger.log(level, "Detail.back..");
int b = Integer.parseInt(getId());
b = b - 1;
logger.log(level, "..Detail.back {0}", b);
back = String.valueOf(b);
return back;
}
public void setBack(String back) {
this.back = back;
}
public String getContent() throws Exception {
logger.log(level, "Detail.getContent..{0}", getId());
message = nntp.getMessage(Integer.parseInt(getId()));
content = message.getContent().toString();
return content;
}
public void setContent(String content) {
this.content = content;
}
}
根据上面的日志,它似乎从未调用过Detail.getContent(),尽管它是视图的一部分:
这个细节很奇怪。在我更改此类以更好地遵循命名约定之前调用了content()。我正在阅读一些Weld和OracleJavaEE6文档,但请不要介意直接阅读一本优秀的手册。我发现描述这一点的文档总是使用@ManagedBeans,但我不是。正如@Kawu在这个答案中所描述的,似乎有很多陷阱。
将@Inject添加到id字段会导致部署错误:
init:
deps-module-jar:
deps-ear-jar:
deps-jar:
library-inclusion-in-archive:
library-inclusion-in-manifest:
compile:
compile-jsps:
In-place deployment at /home/thufir/NetBeansProjects/NNTPjsf/build/web
Initializing...
deploy?DEFAULT=/home/thufir/NetBeansProjects/NNTPjsf/build/web&name=NNTPjsf&contextroot=/NNTPjsf&force=true failed on GlassFish Server 3.1.2
Error occurred during deployment: Exception while loading the app : WELD-001408 Unsatisfied dependencies for type [String] with qualifiers [@Default] at injection point [[field] @Inject private net.bounceme.dur.nntp.Detail.id]. Please see server.log for more details.
/home/thufir/NetBeansProjects/NNTPjsf/nbproject/build-impl.xml:749: The module has not been deployed.
See the server log for details.
BUILD FAILED (total time: 9 seconds)
当然,注入字符串不是问题,可能是一个bug。
我理解你的沮丧,我认为问题更多的是你的设置/理解。但是,仍然很难找到任何真正的问题来回答,也许你下次可以试着分开你的问题。
以下是一些答案:
为什么没有详细说明。getComments()是否执行?
嗯,也许是因为它不在豆子里?我猜你是在重写detail.getContent
?
根据上面的日志,它似乎从未有过细节。调用getContent(),尽管它是视图的一部分:
尝试rendered=true
:-)
@PostConstruct
private void onLoad() {
logger.log(level, "Detail.onLoad..{0}", getId());
}
你在getter中加入了很多逻辑。尝试使用字段而不是getter调试。。。
值2000是一个默认值,只有当id==null时才会发生,它永远不应该这样做。
它看起来像私有字符串id=null
是id为空的完美解释。
请记住,像JSF、CDI和JavaEE这样的现代框架在幕后使用反射、代理和拦截器做了大量工作。例如,不要依赖于对何时(以及多久)调用构造函数的经典理解。
再次,考虑把你的初始化逻辑远离吸气剂。@后构造将是JavaEE规范的创始人为它选择的地方。
老实说:没有什么看起来非常错误,但是你的代码有点混乱,非常难以理解和理解。
尝试删除所有像这样的间接。。。
int b = Integer.parseInt(getId());
... 一切看起来都会好得多。
哦,你为什么要为整个类声明一个固定的日志级别呢?试试这样的
private static final Logger LOG = Logger.getLogger(Some.class);
...
LOG.info("...");
希望这能给你一个开始。请随意发布更多的问题,最好是简短一点,并且回答单一、孤立的方面。
我使用CDI注释定义了一个RequestScoped bean,如下所示。我有几个页面使用同一个bean。当我从一页导航到另一页时。bean obj保持不变。即使我更改了会话(使用不同的用户登录)。bean对象没有改变。 根据RequestScope定义,bean实例应该为每个新请求重新创建。我错过了什么? 我正在使用JSF/Primefaces。从create输入的值。导航到详细信息后可以看到x
问题内容: 我试图将在Spring上下文中定义的bean注入到CDI托管组件中,但没有成功。不会注入Bean,而是在每次执行注入时都会创建一个新实例。我的环境是带有JBoss Weld的Tomcat 7。 Spring ApplicationContext很简单: CDI托管bean如下所示: 这是我的 但是,当我从JSF页面访问属性时,每次访问时都会创建一个新实例。这是一个简单的示例: 我得到以
我的项目正在从使用Java 8的Spring Boot 2.0.4迁移到使用Java 11的Spring Boot 2.1.0。当应用程序使用Spring Boot 2.0.4和Java 8构建并在Docker/Docker Compose中运行时,调用了-带注释的方法,但在迁移到Spring Boot 2.1.0和Java 11之后,不再调用-带注释的方法。 我尝试过从注释切换到实现和,如下所述
本文向大家介绍spring中bean的生命周期详解,包括了spring中bean的生命周期详解的使用技巧和注意事项,需要的朋友参考一下 1.Spring IOC容器可以管理bean的生命周期,Spring允许在bean生命周期内特定的时间点执行指定的任务。 2.Spring IOC容器对bean的生命周期进行管理的过程: ① 通过构造器或工厂方法创建bean实例 ② 为bean的属性设置值和对其他
我对Spring的生命周期感到困惑。 上面的代码片段是否创建了对象? 如果上述答案为真。 a) 然后,对于作用域为“singleton”的bean,获取在上述代码片段中创建的对象。我是对还是错? b)对于范围为“原型”的情况,创建的对象是否未使用。因为,容器总是返回新对象。 上面的代码片段是否创建了对象? 如果答案是假的, Spring框架如何验证bean定义是否正确。 根据亨利的回答 通常,单例
通过构造器或工厂方法创建bean实例; 为bean的属性赋值; 调用bean的初始化方法; 使用bean; 当容器关闭时,调用bean的销毁方法;