我想在我的应用程序中使用JSF 2.3,但WildFly使用2.2 JAR变体.
甲骨文在这里说https://javaserverfaces.java.net/2.3/download.html,不会发布2.3 2 JAR变种.
这个问题之所以出现是因为我阅读了Arjan Tijms 关于 JSF 2.3 的博客文章。在那里,他列出了可以通过 CDI 注入的所有 JSF 工件。虽然HttpServletRequest
提到了,HttpServletResponse
但并没有出现在我一开始并不相信的上述清单上。
为了进行尝试,我设置了一个简单的服务器(JavaEE8、Wildfy22):
@Inject private HttpServletRequest req;
工作得很好@Inject private HttpServletResponse res;
投掷DeploymentException: WELD-001408: Unsatisfied dependencies for type HttpServletResponse
我不明白为什么HttpServletResponse
不应该注射。毕竟,我们的目标是通过简洁的注入来取代复杂的方法链。如果是HttpServletRequest
,FacesContext.getCurrentInstance().getExternalContext().getRequest();
现在可以缩短为上述注入。
好吧,在 的情况下HttpServletResponse
,没有可替换的候选注入FacesContext.getCurrentInstance().getExternalContext().getResponse();
,如上所示。
总结:为什么可以HttpServletRequest
通过 CDI 注射但HttpServletResponse
不能?
我目前在 Wildfly 22 上部署了一个 Web 应用程序,使用 JSF 2.3 和 OpenJDK 11。我目前正在将登录页面从 j_security_check 迁移到以编程方式登录,遵循本文中的 BalusC 示例:
使用 j_security_check 在 Java EE / JSF 中执行用户身份验证
我不会发布登录代码,因为它与 BalusC 的帖子完全相同。
登录过程工作正常,但是在进行此更改后,我在 Wildfly 上收到两个警告。
WELD-000717: Unable to deactivate context org.jboss.weld.module.web.context.http.LazyHttpConversationContextImpl@14d2bf9d when destroying request HttpServletRequestImpl [ GET /app/login/login.xhtml ]
Run Code Online (Sandbox Code Playgroud)
WELD-000335: Conversation context is already active, most likely it was not cleaned up properly during previous request processing: HttpServletRequestImpl [ GET /app/resources/bootstrap/css/bootstrap.min.css]
Run Code Online (Sandbox Code Playgroud)
关于导致这些警告的原因有什么提示吗?
感谢您的帮助!
具有以下代码段:
豆:
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named(value = "directoryBean")
@ViewScoped
public class DirectoryBean implements Serializable {
private static final long serialVersionUID = 1L;
....
}
Run Code Online (Sandbox Code Playgroud)
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
version="2.3">
....
</faces-config>
Run Code Online (Sandbox Code Playgroud)
group.xhtml
<ui:composition ...>
<f:metadata>
<f:viewParam name="id" value="#{directoryBean.id}" />
</f:metadata>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
结果得到异常:
javax.el.PropertyNotFoundException: /group.xhtml @6,64 value="#{directoryBean.id}": Target Unreachable, identifier 'directoryBean' resolved to null
Run Code Online (Sandbox Code Playgroud)
在将faces-config.xml从2.2版语法更改为2.3版语法后得到了它。
意思是,使用带有以下内容的faces-config.xml,一切正常:
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
....
</faces-config>
Run Code Online (Sandbox Code Playgroud)
JSF 2.3.2部署在Payara 4.1.2.172(完整)服务器上,并且还添加到pom.xml中,“提供”范围。
....
<dependencies>
...
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.3.2</version>
<scope>provided</scope> …
Run Code Online (Sandbox Code Playgroud) 我在 JSF2.3 中使用 primefaces
这是我的依赖项的方式
dependencies {
providedCompile 'javax.servlet:javax.servlet-api:4.0.0'
compile group: 'javax.faces', name: 'javax.faces-api', version: '2.3'
compile group: 'org.glassfish', name: 'javax.faces', version: '2.3.3'
compile 'javax.servlet:jstl:1.2'
compile 'org.jboss.weld.servlet:weld-servlet:2.4.5.Final'
compile group: 'org.primefaces', name: 'primefaces', version: '6.2'
}
Run Code Online (Sandbox Code Playgroud)
我的 jsf 文件非常基础
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<f:view>
<h:outputLabel value="Hello, world"/>
<h:form>
<p:selectOneMenu value="#{testView.chosen}"
style="width:200px">
<f:selectItem itemLabel="Select listing template"/>
<f:selectItems value="#{testView.list}"/>
<p:ajax event="change" process="@this" update="@all"/>
</p:selectOneMenu>
</h:form>
</f:view>
</html>
Run Code Online (Sandbox Code Playgroud)
还有我的 viewScoped bean
@Named
@ViewScoped
public class TestView implements Serializable {
String chosen; …
Run Code Online (Sandbox Code Playgroud) 在用户登录时更新 HTTP 会话是一种常见的最佳实践。这将强制使用新的会话 ID,避免会话固定漏洞。
当涉及@SessionScoped bean 时,是否有使用 CDI 实现此功能的首选模式?困难在于,通过使当前的 HTTP 会话无效,您将在下一个请求中获得一个不同的会话范围的 bean,但直到下一个请求才会如此。
例如,假设一个会话 bean 用于存储用户登录信息:
@Named("sessionbean")
@SessionScoped
public class SessionBean implements Serializable {
private int userId;
private String username;
private List<String> privileges;
// Accessors omitted
}
Run Code Online (Sandbox Code Playgroud)
另一个用于管理登录的 bean:
@Named("loginbean")
@ViewScoped
public class LoginBean implements Serializable {
private String username;
private String password;
@Inject private SessionBean session;
@Inject private SessionManager sessionManager;
@Inject private PrivilegeManager privilegeManager;
public String doLogin() {
String destinationUrl;
if (validate(username, password)) {
FacesContext context = FacesContext.getCurrentInstance();
// force …
Run Code Online (Sandbox Code Playgroud) @FacesConverter
并且@FacesValidator
不符合EJB或JSF 2.2以下的托管bean注入点的条件。
他们应该用JSF 2.3(目前作为工作的里程碑使用附加专用)managed
属性以@FacesConverter
和@FacesValidator
为提到这里。
在JSF 2.1中,很少有JSF工件是注入目标。在JSF 2.2中,可以通过大量其他工件进行注入,但实际上注入最重要的那些对象(转换器和验证器)却被冷落了。
在JSF 2.3中,现在已经解决了这一问题,因为以下伪像已添加到注入目标列表中:
javax.faces.convert.Converter
javax.faces.validator.Validator
javax.faces.component.behavior.Behavior
但是,与该清单中已经存在的伪像相反,这些新的3个不是自动注入目标。他们只会变得那么当一个所谓的新属性上相应的注释“管理”
@FacesConverter
,@FacesValidator
并@Behavior
设置为true。 此外,通过将@Qualified
注释添加到其定义中,所有这三个注释均已升级为CDI限定符。的现有属性
@FacesConverter
,@FacesValidator
并@Behavior
没有被修改,这意味着它们都结合,因为是新属性“管理”。
managed
但是,该属性在Mojarra 2.3.0-m02中不可用。
是因为一个里程碑?是否取决于特定的Weld / CDI版本?我目前正在使用GlassFish Server 4.1。这里提到了不同的工件版本(服务器版本提供的默认Weld版本为2.2.2 final)。
JavaEE,JSF-2.3,Websocket,WebApplication,WildFly.
对于每个用户,将创建一个会话,在该会话中进行操作,授权,身份验证等.在15分钟不活动后,由于web.xml的设置,会话将自动销毁-
<session-config>
<session-timeout>15</session-timeout>
</session-config>
Run Code Online (Sandbox Code Playgroud)
在JSF-2.3中可用的WebSocket,所以我决定这样做ExitBean.java -
@Inject
@Push(channel = "exit")
PushContext push;
@PreDestroy
public void sessionTimeOut() {
push.send("exitEvent");
}
Run Code Online (Sandbox Code Playgroud)
在页面上,分别是exit.xhtml -
<h:form >
<f:websocket channel="exit" scope="session">
<f:ajax event="exitEvent" onevent="PF('dlg1').show()"/>
</f:websocket>
</h:form>
Run Code Online (Sandbox Code Playgroud)
在会话结束时,根据日志判断,该sessionTimeOut()
方法仍然有效@PreDestroy
,但页面上没有响应.
为了测试,我在exit.xhtml页面上放置了一个按钮,通过单击sessionTimeOut()
调用该方法.单击此按钮时,事件 - "exitEvent"按预期执行,调用PrimeFaces脚本PF('dlg1').show()
,该脚本显示一个对话框.
我怀疑websockets甚至比@Predestroy
调用方法更早被杀死.
websocket还有另一种选择,它看起来像这样:
<h:form >
<f:websocket channel="exit" scope="session" onclose="PF('dlg1').show()"/>
</h:form>
Run Code Online (Sandbox Code Playgroud)
但它只在页面加载时才有效,并且对会话结束时没有反应.
两个问题:
在网上搜索时,我发现应该可以将一些方便的 JSF 对象 @Inject 到 CDI bean 中,这些对象应该由 JSF 生成并通过 javax.faces.annotation.* 中的限定符公开(如 @RequestMap 或 @SessionMap)。
但是,我无法将这些资源 @Inject 到 CDI Bean 中。即使注入ExternalContext
或FacesContext
失败,如 JSF 2.3 规范中所述,也应该可以 @Inject 以及以下内容:
javax.faces.context.Flash
javax.servlet.http.HttpSession <-- 这个正在工作
@RequestScoped
public class SimpleRequestParamReportProvider implements ReportParamsProvider {
@Inject // <-- FAILS
ExternalContext externalContext;
@Inject // <-- FAILS
FacesContext facesContext;
@Inject @RequestMap // <-- FAILS
Map<String, Object> requestMap;
@Inject // <-- WORKS
HttpSession httpSession;
Run Code Online (Sandbox Code Playgroud)
应用程序启动时显示错误:
在注入点 [BackedAnnotatedField] @Inject report.SimpleRequestParamReportProvider.facesContext 处带有限定符 @Default 的 FacesContext 类型的依赖关系不满足
我正在使用JBoss …
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd似乎没有退出.2.2工作正常.
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
version="2.3">
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
应用程序工作正常,但IntelliJ显示Red中的所有内容,因为无法验证模式.