I am studying on developing JSF 2.2 component jar library. I have developed a simple MyDataTablecomponent for this purpose.
MyDataTableLib.jar contains 3 packages:
1) META-INF which contains following MyDataTableTag.taglib.xml file
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
<namespace>http:java.sun.com/MyDataTableTag</namespace>
<tag>
<tag-name>MyDataTableTag</tag-name>
<component>
<component-type>com.components.MyDataTable</component-type>
<renderer-type>com.renderer.MyRenderer</renderer-type>
</component>
<attribute>
<name>title</name>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>binding</name>
<required>true</required>
<deferred-value>com.components.MyDataTable</deferred-value>
</attribute>
</tag>
</facelet-taglib>
2)com.componentswhich contains following MyDataTablecomponent
package com.components;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
#FacesComponent(value = MyDataTable.MY_TYPE)
public class MyDataTable extends UIComponentBase {
public static final String MY_FAMILY = "com.components.MyDataTable";
public static final String MY_TYPE = "com.components.MyDataTable";
public static final String MY_RENDERER_TYPE = "com.renderer.MyRenderer";
String Title, columnnames[], data[][];
DataBaseManagement db;
#Override
public String getFamily() {
return MY_FAMILY;
}
public MyDataTable() throws ClassNotFoundException, SQLException {
setRendererType(MY_RENDERER_TYPE);
db = new DataBaseManagement("jdbc:mysql://localhost:3306/fakulte", "root", "");
}
public String getTitle() {
return Title;
}
public void setTitle(String Title) {
this.Title = Title;
}
public String[] getColumnnames() {
return columnnames;
}
public void setColumnnames(String[] columnnames) {
this.columnnames = columnnames;
}
public String[][] getData() {
return data;
}
public void setData(String[][] data) {
this.data = data;
}
public void executeQuery(String query) throws SQLException {
ArrayList<HashMap<String, String>> result = db.getQuery(query);
Object cols[] = result.get(0).keySet().toArray();
columnnames = new String[cols.length];
data = new String[result.size()][cols.length];
for (int c = 0; c < cols.length; c++) {
columnnames[c] = cols[c].toString();
}
for (int r = 0; r < result.size(); r++) {
for (int c = 0; c < columnnames.length; c++) {
data[r][c] = result.get(r).get(columnnames[c]);
}
}
Title = db.getLastQueryTitle();
}
#Override
public Object saveState(FacesContext context) {
Object val[] = new Object[4];
val[0] = super.saveState(context);
val[1] = Title;
val[2] = columnnames;
val[3] = data;
return val;
}
#Override
public void restoreState(FacesContext context, Object state) {
Object val[] = (Object[]) state;
super.restoreState(context, val[0]);
Title = (String) val[1];
columnnames = (String[]) val[2];
data = (String[][]) val[3];
}
}
3) com.rendererwhich contains MyRendererrenderer class
package com.renderer;
import com.components.MyDataTable;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
#FacesRenderer(componentFamily = MyDataTable.MY_FAMILY,
rendererType = MyDataTable.MY_RENDERER_TYPE)
public class MyRenderer extends Renderer {
#Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
super.encodeBegin(context, component);
if (component != null) {
encodeTable(context.getResponseWriter(), (MyDataTable) component);
}
}
#Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
super.encodeEnd(context, component);
ResponseWriter out = context.getResponseWriter();
out.startElement("h3", component);
out.write("Sayfa Sonu-------");
out.endElement("h3");
}
private void encodeTable(ResponseWriter out, MyDataTable table) throws IOException {
if (table.getTitle() != null) {
out.startElement("h1", table);
out.write(table.getTitle());
out.endElement("h1");
}
if (table.getData() != null) {
out.startElement("table", table);
out.writeAttribute("border", "1", "border");
if (table.getColumnnames() != null) {
out.startElement("tr", table);
String col[] = table.getColumnnames();
for (int i = 0; i < col.length; i++) {
out.startElement("td", table);
out.write(col[i]);
out.endElement("td");
}
out.endElement("tr");
}
String data[][] = table.getData();
for (int r = 0; r < data.length; r++) {
out.startElement("tr", table);
for (int c = 0; c < data[r].length; c++) {
out.startElement("td", table);
out.write(data[r][c]);
out.endElement("td");
}
out.endElement("tr");
}
out.endElement("table");
}
}
}
When I include this jar library in another project as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:t="http:java.sun.com/MyDataTableTag">
<head>
<title>TODO supply a title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<h:form>
<h:inputText binding="#{Bean.input}"/>
<h:commandButton value="Execute query" action="#{Bean.executeQuery()}"/>
<t:MyDataTableTag title="Hello" binding="#{Bean.table}"/>
</h:form>
</body>
</html>
Expression Error: Named Object: com.components.MyDataTable not found.error message is thrown.
I am using NetBeans 8.0. I need help.
Thank you BalusC
I put new DataBaseManagement() in try-catch but no exception was thrown. I removed <rtexprvalue>and <deferred-value>attributes from tag lib.xmland nothing changed. Stack trace is as follows:
javax.faces.FacesException: Expression Error: Named Object: com.components.MyDataTable not found.
at com.sun.faces.application.ApplicationImpl.createComponentApplyAnnotations(ApplicationImpl.java:1933)
at com.sun.faces.application.ApplicationImpl.createComponentApplyAnnotations(ApplicationImpl.java:1968)
at com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:1151)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.createComponent(ComponentTagHandlerDelegateImpl.java:499)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:172)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:161)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:980)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:99)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
I solved the problem.
Do not forget to put an empty faces-config.xml file (containing only
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="java.sun.com/xml/ns/javaee"; xmlns:xsi="w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="java.sun.com/xml/ns/javaee java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd";
version="2.1">
</faces-config>
) in your META-INF package.
Related
I am trying to call a secured EJB method on server load but I am getting exception:
09:49:58,011 ERROR [org.jboss.as.ejb3.invocation] (ServerService Thread Pool -- 54) JBAS014134: EJB Invocation failed on component SecuredEJB for method public java.lang.String org.jboss.as.quickstarts.ejb_security.SecuredEJB.getSecurityInfo(): javax.ejb.EJBAccessException: JBAS014502: Invocation on method: public java.lang.String org.jboss.as.quickstarts.ejb_security.SecuredEJB.getSecurityInfo() of bean: SecuredEJB is not allowed
at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:114) [jboss-as-ejb3-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:86) [jboss-as-ejb3-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [jboss-as-ejb3-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [jboss-as-ejb3-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) [jboss-as-ee-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [jboss-as-ejb3-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) [jboss-as-ee-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:185) [jboss-as-ee-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:185) [jboss-as-ee-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:73) [jboss-as-ee-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.quickstarts.ejb_security.SecuredEJB$$$view1.getSecurityInfo(Unknown Source) [classes:]
at org.jboss.as.quickstarts.ejb_security.SecuredEJBServlet.init(SecuredEJBServlet.java:55) [classes:]
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1194) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1100) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3593) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3802) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:163) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.web.deployment.WebDeploymentService.access$000(WebDeploymentService.java:61) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:96) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_55]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_55]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_55]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.2.Final-redhat-1.jar:2.1.2.Final-redhat-1]
My project structure is:
SecuredEJBServlet.java
#SuppressWarnings("serial")
#WebServlet("/SecuredEJBServlet")
#ServletSecurity(#HttpConstraint(rolesAllowed = "quickstarts"))
public class SecuredEJBServlet extends HttpServlet {
#EJB
private SecuredEJB securedEJB;
#Override
public void init(javax.servlet.ServletConfig arg0) throws javax.servlet.ServletException{
Subject s = CMnJAASLogin.loginMethod();
runAs(s);
super.init(arg0);
System.out.println("Inside init...");
securedEJB.getName();
//securedEJB.getSecurityInfo();
}
private void runAs(Subject s){
Subject.doAs(s, new PrivilegedAction<Object>() {
#Override
public Object run() {
System.out.println("Inside privileged action");
securedEJB.getSecurityInfo();
return null;
}
});
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
securedEJB.getName();
String principal = securedEJB.getSecurityInfo();
...
}
SecuredEJB.java
#Stateless
#DeclareRoles("java")
#SecurityDomain("custom")
public class SecuredEJB {
#Resource
private SessionContext ctx;
#RolesAllowed({ "java" })
public String getSecurityInfo() {
Principal principal = ctx.getCallerPrincipal();
return principal.toString();
}
#PermitAll
public void getName(){
System.out.println(principal.getName());
}
}
CMnAuthenticator.java
public class CMnAuthenticator extends UsernamePasswordLoginModule{
#Override
protected String getUsersPassword() throws LoginException {
return "java";
}
#Override
protected boolean validatePassword(String passwordWant, String passwordHave){
return true;
}
#Override
protected Group[] getRoleSets() throws LoginException {
HashMap setsMap = new HashMap();
String groupName = "Roles";
Group group = (Group) setsMap.get(groupName);
if (group == null) {
group = new SimpleGroup(groupName);
setsMap.put(groupName, group);
}
try {
Principal p = super.createIdentity("quickstarts");
group.addMember(p);
}
catch (Exception e) {
e.printStackTrace();
}
Group[] roleSets = new Group[setsMap.size()];
setsMap.values().toArray(roleSets);
return roleSets;
}
}
CMnEJBAuthenticator.java
public class CMnEJBAuthenticator extends UsernamePasswordLoginModule {
#Override
protected String getUsersPassword() throws LoginException {
return "java";
}
#Override
protected boolean validatePassword(String passwordWant, String passwordHave){
return true;
}
#Override
protected Group[] getRoleSets() throws LoginException {
System.out.println("Inside CMnEJBAuthenticator:getRoleSets...");
HashMap setsMap = new HashMap();
String groupName = "Roles";
Group group = (Group) setsMap.get(groupName);
if (group == null) {
group = new SimpleGroup(groupName);
setsMap.put(groupName, group);
}
try {
Principal p = super.createIdentity("java");
group.addMember(p);
}
catch (Exception e) {
e.printStackTrace();
}
Group[] roleSets = new Group[setsMap.size()];
setsMap.values().toArray(roleSets);
return roleSets;
}
}
jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.org/schema/jbossas
http://www.jboss.org/schema/jbossas/jboss-web_7_2.xsd">
<!-- Configure usage of the security domain "other" -->
<security-domain>servlet-security-quickstart</security-domain>
<disable-audit>true</disable-audit>
</jboss-web>
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!-- Configure login to be HTTP Basic -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>RealmUsersRoles</realm-name>
</login-config>
<servlet>
<servlet-name>bootstrap</servlet-name>
<servlet-class>org.jboss.as.quickstarts.ejb_security.SecuredEJBServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>bootstrap</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
standalone.xml
<security-domain name="custom" cache-type="default">
<authentication>
<login-module code="org.jboss.as.quickstarts.ejb_security.others.CMnEJBAuthenticator" flag="required">
<module-option name="unauthenticatedIdentity" value="Super"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="servlet-security-quickstart" cache-type="default">
<authentication>
<login-module code="org.jboss.as.quickstarts.ejb_security.others.CMnAuthenticator" flag="required">
<module-option name="unauthenticatedIdentity" value="Super"/>
</login-module>
</authentication>
</security-domain>
Jaas Authentication:
package org.jboss.as.quickstarts.ejb_security.others;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.LoginContext;
import java.io.IOException;
public class CMnJAASLogin {
public static Subject loginMethod(){
LoginContext lc = null;
CallbackHandler cabHndlr = new CallbackHandler() {
#Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks[i];
nc.setName("java");
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks[i];
pc.setPassword("java".toCharArray());
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
};
try {
lc = new LoginContext("custom", cabHndlr);
lc.login();
return lc.getSubject();
}catch(Exception ex){
ex.printStackTrace();
}
return null;
}
}
Any idea what I am missing?
Note: I am working on JBoss EAP 6.4 and java 1.7
Adding #RunAs("java") to Servlet class solves this immediate problem.
But in case, i need to deny access for other users, RunAs annotation won't help there.
So, I am required to solve it in this way(if no user is calling the method/ejb/servlet, use "java" else use that users' role.
I have not tried this, but §15.3.1 of the servlet spec says that you just need to add a run-as element to your servlet definition in the web.xml:
<servlet>
<servlet-name>bootstrap</servlet-name>
<servlet-class>org.jboss.as.quickstarts.ejb_security.SecuredEJBServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<run-as>java</run-as>
</servlet>
However, it is not completely clear whether or not the actual authenticated principal will be propagated to the EJBs for the normally authenticated servlet calls. You will have to try it and see.
I solved it after using org.jboss.security.ClientLoginModule in AppConfigurationProperty.
Finally, JAAS class looks like this:
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class CMnJAASLogin {
public static LoginContext loginMethod() {
LoginContext lc = null;
CallbackHandler cabHndlr = new CallbackHandler() {
#Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks[i];
nc.setName("java");
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks[i];
pc.setPassword("java".toCharArray());
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
};
try {
String configurationName = "JBoss Test";
Configuration config = new JBossJaasConfiguration(configurationName);
lc = new LoginContext(configurationName, new Subject(), cabHndlr, config);
return lc;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
static class JBossJaasConfiguration extends Configuration {
private final String configurationName;
JBossJaasConfiguration(String configurationName) {
this.configurationName = configurationName;
}
#Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
if (!configurationName.equals(name)) {
throw new IllegalArgumentException("Unexpected configuration name '" + name + "'");
}
return new AppConfigurationEntry[]{
createClientLoginModuleConfigEntry(),
};
}
private AppConfigurationEntry createClientLoginModuleConfigEntry() {
Map<String, String> options = new HashMap<String, String>();
options.put("multi-threaded", "true");
options.put("restore-login-identity", "true");
return new AppConfigurationEntry("org.jboss.security.ClientLoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
}
}
}
Whole project is uploaded to: https://github.com/shekharswaraj/EJBSecurity
NOTE: It is just a test project with many hard coded values. The whole project has been modified on top of ejb-security project from EAP6.4 quickstart.
This question already has answers here:
javax.el.PropertyNotFoundException: Property 'foo' not found on type com.example.Bean
(6 answers)
Closed 6 years ago.
My problem is the following. I've a list which i s well created, but I can't manage to display it on my web page.
Here is the pojo :
package trainforjava.domain;
public class Question {
public int id;
public String askedQuestion;
public String proposal;
public Question() {
super();
}
public Question(int id, String askedQuestion, String proposal) {
super();
this.id = id;
this.askedQuestion = askedQuestion;
this.proposal = proposal;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setAskedQuestion(String askedQuestion) {
this.askedQuestion = askedQuestion;
}
public String getAskedQuestion() {
return askedQuestion;
}
public void setQuestion(String askedQuestion) {
this.askedQuestion = askedQuestion;
}
public String getProposal() {
return proposal;
}
public void setProposal(String proposal) {
this.proposal = proposal;
}
#Override
public String toString() {
return "Question [id=" + id + ", askedQuestion=" + askedQuestion + "]";
}
}
Here is the managed bean :
package trainforjava.domain;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import trainforjava.util.QuestionCreator;
#ManagedBean
public class QuestionBean {
public List<String> proposals;
public List<Question> questions;
public QuestionCreator creator = new QuestionCreator();
public QuestionBean() {
System.out.println("beforecreate");
questions = creator.createQuestions();
System.out.println(questions);
// proposals = creator.createProposals(0);
}
public List<String> getProposals() {
return proposals;
}
public void setProposals(List<String> proposals) {
this.proposals = proposals;
}
public List<Question> getQuestions() {
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
}
Here is the pojo creating from a properties file :
package trainforjava.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.stereotype.Component;
import trainforjava.domain.Question;
public class QuestionCreator {
List<Question> questions =new ArrayList<Question>();
List<String> proposals = new ArrayList<String>();
public List<Question> createQuestions() {
final Properties properties = new Properties();
InputStream input = null;
System.out.println("createQuestions");
try {
input = getClass().getResourceAsStream("/questions.properties");
// load a properties file
properties.load(input);
// get the property value and print it out
for (int i = 0; i < properties.size(); i++) {
Question question = new Question();
StringBuilder sb = new StringBuilder();
sb.append("question-").append(i);
String askedQuestion = properties.getProperty(sb.toString());
question.setAskedQuestion(askedQuestion);
question.setId(i);
questions.add(question);
}
} catch (final IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
return questions;
}
public List<String> createProposals(int key) {
final Properties properties = new Properties();
InputStream input = null;
System.out.println("createProposals");
try {
input = getClass().getResourceAsStream("/proposals.properties");
// load a properties file
properties.load(input);
for(int i =0 ; i < proposals.size(); i++){
int idQuestion = key;
System.out.println("createProposals id" + idQuestion);
StringBuilder sb = new StringBuilder();
sb.append("proposal-").append(idQuestion).append("-").append(i);
String proposal = properties.getProperty(sb.toString());
proposals.add(proposal);
System.out.println(proposals);
}
} catch (final IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
return proposals;
}
}
The console print me the list created, which name is "questions", but also print me a stacktrace :
beforecreate
createQuestions
[Question [id=0, askedQuestion=Quelle interface est implémentée par la Classe ArrayList ?], Question [id=1, askedQuestion=Quelle interface est implémentée par la Classe HashMap ?], Question [id=2, askedQuestion=Quelle interface est implémentée par la Classe Vector ?]]
août 23, 2016 2:29:19 AM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
GRAVE: Error Rendering View[/index.xhtml]
javax.el.ELException: /index.xhtml: Property 'askQuestion' not found on type trainforjava.domain.Question
at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
at com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:385)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:161)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:890)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:890)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:458)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:134)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
août 23, 2016 2:29:19 AM com.sun.faces.context.ExceptionHandlerImpl log
1100: JSF1073 : javax.el.ELException intercepté durant le traitement de RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=/index.xhtml: Property 'askQuestion' not found on type trainforjava.domain.Question
août 23, 2016 2:29:19 AM com.sun.faces.context.ExceptionHandlerImpl log
1100: /index.xhtml: Property 'askQuestion' not found on type trainforjava.domain.Question
javax.el.ELException: /index.xhtml: Property 'askQuestion' not found on type trainforjava.domain.Question
at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
at com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:385)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:161)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:890)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:890)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:458)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:134)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
And then, the index.xhtml which is supposed to display this list :
<!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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Test</title>
</h:head>
<h:body>
Question :
<h:form>
<h:dataTable value="#{questionBean.questions}" var="question">
<h:column>
#{question.askQuestion}
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
Can someone help me please ?
The property name is actually askedQuestion, and not askQuestion.
I have a JSF application that uses several java classes to do dynamic compilation of java code.
Code is written in a text area and compiled by pressing an h:commandButton via Ajax.
Problem occurs when i press more than 2 or 3 times to compile different codes.
Here is the stack trace :
javax.faces.application.ViewExpiredException: viewId:/home.xhtml - View /home.xhtml could not be restored.
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:210)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:121)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Unknown Source)
If i set the attribute transient=true to f:view, the problem stops since the state is not saved, but that restricts me from using other functionality like saving my source file in database for user to retrieve in later time.
home.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Home Page</title>
</h:head>
<h:body>
<f:view transient="true">
<h:form prependId="false">
<h:panelGrid columns="1">
<h:inputTextarea id="codeArea" rows="25" cols="70" value="#{user.userInputCode}" />
<h:outputText id="messages" value="#{user.compilationMessages}"/>
</h:panelGrid>
<h:commandButton value="Compile">
<f:ajax execute="codeArea" render="messages" listener="#{user.compileCode()}"/>
</h:commandButton>
</h:form>
</f:view>
</h:body>
</html>
UserBean
#Named(value = "user")
#SessionScoped
public class UserBean implements Serializable {
private String userInputCode;
private String compilationMessages;
private CompilerBean compiler;
public UserBean() {
compiler = new CompilerBean();
userInputCode = compiler.getDefaultCodeModel();
}
public String getUserInputCode() {
return userInputCode;
}
public void setUserInputCode(String userInputCode) {
this.userInputCode = userInputCode;
}
public String getCompilationMessages() {
return compilationMessages;
}
public void compileCode() throws Exception {
if (!compiler.isValidClass(userInputCode)) {
compilationMessages = "Please provide a correct class format";
} else {
if (compiler.compile(userInputCode)) {
compilationMessages = "Compilation Success!";
} else {
compilationMessages = compiler.getDiagnosticMessages();
}
}
}
Compiler
public class CompilerBean implements CompilationInterface {
private JavaCompiler compiler;
private DiagnosticCollector diagCollector;
private StandardJavaFileManager fileManager;
private String sourceFile;
public CompilerBean() {
sourceFile = DEFAULT_SOURCEFILE;
}
public boolean compile(String inputCode) throws Exception {
compiler = ToolProvider.getSystemJavaCompiler();
diagCollector = new DiagnosticCollector();
fileManager = compiler.getStandardFileManager(diagCollector, null, null);
File outputFile = new File(CLASS_FILES_PATH);
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(outputFile));
String className = extractClassName(inputCode);
sourceFile = className + JAVA_POSTFIX;
JavaFileObject sourceObject = new CompilerJavaObject(sourceFile, inputCode);
Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagCollector, null, null, fileObjects);
deleteCompiledFiles();
return task.call();
}
public String getDiagnosticMessages() {
String message = "";
List<Diagnostic> diagErrors = diagCollector.getDiagnostics();
for (Diagnostic d : diagErrors) {
message = ("Error: " + d.getLineNumber() + " Cause: " + d.getMessage(null));
}
return message;
}
private void deleteCompiledFiles() {
File f = new File(CLASS_FILES_PATH);
for (File classFile : f.listFiles()) {
classFile.delete();
}
}
public String getDefaultCodeModel() {
return DEFAULT_CLASS_MODEL;
}
public String getSourceFile() {
return sourceFile;
}
/*
* Extracts the class name from the input code
*/
private String extractClassName(String input) {
String className = input.replaceAll(COMMENTS_REGEX, "");
className = className.replaceAll(IMPORTS_REGEX, "");
className = className.replaceAll(CLASS_BODY, "");
className = className.replaceAll(CLASS_REGEX, "").trim();
return className;
}
/*
* Checks if the input code is in a valid class format
*/
public boolean isValidClass(String input) {
Pattern pat1 = Pattern.compile(COMMENTS_REGEX);
Pattern pat2 = Pattern.compile(IMPORTS_REGEX);
Pattern pat3 = Pattern.compile(CLASS_REGEX);
Matcher m1 = pat1.matcher(input);
Matcher m2 = pat2.matcher(input);
Matcher m3 = pat3.matcher(input);
return m3.lookingAt() || m1.lookingAt() || m2.lookingAt();
}
}
Compiler uses 2 more class an Interface with some String constants and a class that extends SimpleJavaFileObject
There are a few approaches you can take:
Turn partial-state saving true in web.xml
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>true</param-value>
</context-param>
Increase the number of logical views in session. Note that JSF caches your views and there is a limit to that cache.
<context-param>
<param-name>com.sun.faces.NUMBER_OF_LOGICAL_VIEWS_IN_SESSION</param-name>
<param-value>50</param-value>
</context-param>
In cases where the above doesn't solve your problem, write a handler for ViewExpiredException and restore the view programatically. This will refresh your view on the client side(might not be the best user experience, though)
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.application.ViewHandler;
import javax.faces.application.ViewHandlerWrapper;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
public class MyViewExpiredHandler extends ViewHandlerWrapper {
private ViewHandler wrapped;
private static Map<String, Boolean> viewsToProcess = new HashMap<String, Boolean>();
//assuming these xhtmls throw ViewExpiredException
static {
viewsToProcess.put("/view/xxxx.xhtml", true);
viewsToProcess.put("/view/aaa.xhtml", true);
viewsToProcess.put("/view/yyy.xhtml", true);
}
public MyViewExpiredHandler(ViewHandler parent) {
this.wrapped = parent;
}
#Override
public ViewHandler getWrapped() {
return wrapped;
}
#Override
public UIViewRoot restoreView(FacesContext context, String viewId) {
UIViewRoot viewRoot = super.restoreView(context, viewId);
if(viewsToProcess.containsKey(viewId) && viewRoot == null) {
viewRoot = super.createView(context, viewId);
super.initView(context);
try {
super.renderView(context, viewRoot);
} catch (FacesException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return viewRoot;
}
}
I have to implement I18N based on domain using JSF2.
For example if the domain is
www.bookstore.com --> it should go to english site
www.bookstore.com.cn --> it should go to chinese site
www.bookstore.co.jp --> it should go to japanese site
We have all properties files with proper translation.
When i change my browser language/locale, i could able to see the translated content.
But we don't need that behavior actually.
I am setting the locale based on domain in Filter, It seems not working.
Here is my code, What is wrong in this code, Where is the problem ?
AuthenticationFilter.java
public class AuthenticationFilter implements Filter {
private static Log log = LogFactory.getLog(AuthenticationFilter.class);
#Override
public void init(FilterConfig config) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
FacesContext facesContext = FacesUtil.getFacesContext(httpRequest, httpResponse);
facesContext.getExternalContext().setResponseCharacterEncoding("UTF-8");
Locale requestLocale = LocaleUtil.getLocaleFromDomain(httpRequest);
if(requestLocale == null){
requestLocale = LocaleUtil.getDefault();
}
facesContext.getViewRoot().setLocale(requestLocale);
chain.doFilter(httpRequest, httpResponse);
}
#Override
public void destroy() {
}
}
FacesUtil.java
public class FacesUtil {
public static FacesContext getFacesContext(HttpServletRequest request, HttpServletResponse response) {
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext == null) {
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
facesContext = contextFactory.getFacesContext(request.getSession().getServletContext(), request, response, lifecycle);
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "");
facesContext.setViewRoot(view);
FacesContextWrapper.setCurrentInstance(facesContext);
}
return facesContext;
}
// Wrap the protected FacesContext.setCurrentInstance() in a inner class.
private static abstract class FacesContextWrapper extends FacesContext {
protected static void setCurrentInstance(FacesContext facesContext) {
FacesContext.setCurrentInstance(facesContext);
}
}
}
LocaleUtil.java
public class LocaleUtil {
public static Locale getLocaleFromDomain(HttpServletRequest request){
Locale locale=Locale.getDefault();
String domain = request.getHeader("HOST");
if(domain.contains(".com.cn"))
{
locale = new Locale(Locale.SIMPLIFIED_CHINESE.getLanguage(), Locale.CHINA.getCountry());
}else if(domain.contains(".co.jp"))
{
locale = new Locale(Locale.JAPANESE.getLanguage(), Locale.JAPAN.getCountry());
}else if(domain.contains(".co.kr"))
{
locale = new Locale(Locale.KOREAN.getLanguage(), Locale.KOREA.getCountry());
}else if(domain.contains(".com.tw"))
{
locale = new Locale(Locale.CHINESE.getLanguage(), Locale.TAIWAN.getCountry());
}
return locale;
}
public static Locale getDefault() {
Locale defaultLocale = new Locale("en", "US");
return defaultLocale;
}
}
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en_US</supported-locale>
<supported-locale>zh</supported-locale>
<supported-locale>zh_CN</supported-locale>
<supported-locale>zh_TW</supported-locale>
<supported-locale>ja</supported-locale>
<supported-locale>ja_JP</supported-locale>
</locale-config>
<resource-bundle>
<base-name>com.bookstore.component.BookStoreTextHandler</base-name>
<var>msg</var>
</resource-bundle>
</application>
</faces-config>
BookStoreTextHandler.java
public class BookStoreTextHandler extends ResourceBundle {
protected static final String BUNDLE_NAME = "/var/app/conf/bookstore";
protected static final String BUNDLE_EXTENSION = "properties";
protected static final Control UTF8_CONTROL = new UTF8Control();
public BookStoreTextHandler() {
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
setParent(ResourceBundle.getBundle(BUNDLE_NAME, locale, UTF8_CONTROL));
}
#Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}
#Override
public Enumeration<String> getKeys() {
return parent.getKeys();
}
protected static class UTF8Control extends Control {
#Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
ResourceBundle bundle = null;
InputStreamReader reader = null;
FileInputStream fis = null;
try {
File file = new File(resourceName);
if (file.isFile()) { // Also checks for existance
fis = new FileInputStream(file);
reader = new InputStreamReader(fis, Charset.forName("UTF-8"));
bundle = new PropertyResourceBundle(reader);
}
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(fis);
}
return bundle;
}
}
}
i have bookstore.properties, bookstore_en.properties, bookstore_en_US.properties, bookstore_zh.properties, bookstore_zh_CN.properties, bookstore_zh_TW.properties, bookstore.properties_ja, bookstore_ja_JP.properties, files in /var/app/conf/ location.
introPage.xhtml
<ui:composition lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:ui="http://java.sun.com/jsf/facelets">
<div class="frame">
<h1>#{msg['bookstore.intro.title']}</h1>
</div>
<div>
<p style="line-height: 1.6em; font-family: Verdana, Arial, sans-serif;">
<h:outputText value="#{msg['bookstore.intro.paragraph.1']}" escape="false"/>
</p>
<p style="line-height: 1.6em; font-family: Verdana, Arial, sans-serif;">
<h:outputText value="#{msg['bookstore.intro.paragraph.2']}" escape="false"/>
</p>
<p style="line-height: 1.6em; font-family: Verdana, Arial, sans-serif; font-weight: bold;">
<h:outputText value="#{msg['bookstore.intro.paragraph.3']}" escape="false"/>
</p>
</div>
</ui:composition>
When i am trying from different domains [ i have changed my host file locally ],
when i debug the filter code, it is giving correct Locale based on domain.
But don't know why always getting english content.
But if i change the browser language, i can see the translated content.
What is wrong in this code ?
I have a PhaseListener and does not work. But in the computer of my co-worker if it works.
I use netbeans 6.8 With Glassfish 2.1 and Windows 32 bits
The PhaseListener:
package mx.udg.cgti.seguridad.listener;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseListener;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import mx.udg.cgti.seguridadcore.negocio.ProcesosCNLocal;
public class SeguridadCorePhaseListener implements PhaseListener {
public SeguridadCorePhaseListener() {
}
public void beforePhase(PhaseEvent pe) {
System.out.println("beforePhase");
}
public void afterPhase(PhaseEvent pe) {
System.out.println("afterPhase");
if (pe.getPhaseId().equals(PhaseId.RESTORE_VIEW)) {
if (pe.getFacesContext() != null) {
String pagina = pe.getFacesContext().getViewRoot().getViewId();
if (!"/Inicio.xhtml".equalsIgnoreCase(pagina) && !"/Login.xhtml".equalsIgnoreCase(pagina) && pagina.contains(".xhtml")) {
loggedIn();
}
}
}
}
private void loggedIn() {
String pagina = "";
Long token = obtenToken();
if (token != null) {
String result = "";
result = lookupProcesosCNLocal().getSesionActiva(token);
if ("".equalsIgnoreCase(result)) {
result = null;
}
// System.out.println("RESULT " + result);
if (result == null) {
pagina = new String("sessionTimeout");
}
} else {
pagina = new String("sinSession");
}
// System.out.println(" PAGINA :- " + pagina + " TOKEN " + token);
if (!pagina.equalsIgnoreCase("")) {
// System.out.println("REGLAS DE NAVEGACION TRABAJANDO HACIA " + pagina);
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, pagina);
fc.renderResponse();
}
}
private Long obtenToken() {
Long token = null;
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
Object t = request.getAttribute("token");
if (t == null) {
Object obj=null;
if(session != null){
obj = session.getAttribute("token");
if(obj == null){
obj = request.getParameter("token");
}
}else{
obj = request.getParameter("token");
}
if (obj != null) {
if (obj != null && !"".equalsIgnoreCase(obj.toString())) {
token = Long.parseLong(obj.toString());
}
}
} else {
token = Long.parseLong(t.toString());
}
if (token != null) {
request.setAttribute("token", token);
if(session == null){
session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
}
session.setAttribute("token", token);
}
return token;
}
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
private ProcesosCNLocal lookupProcesosCNLocal() {
try {
Context c = new InitialContext();
return (ProcesosCNLocal) c.lookup("java:comp/env/ProcesosCN");
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
}
faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<!-- =========== FULL CONFIGURATION FILE ================================== -->
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>logear</from-outcome>
<to-view-id>/Login.xhtml</to-view-id>
<redirect>1</redirect>
</navigation-case>
<navigation-case>
<from-outcome>sessionTimeout</from-outcome>
<to-view-id>/LoginError.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>sinSession</from-outcome>
<to-view-id>/LoginError.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<application>
<message-bundle>
mx.udg.cgti.seguridad.boundle.MiBoundle
</message-bundle>
</application>
<lifecycle>
<phase-listener>mx.udg.cgti.seguridad.listener.SeguridadCorePhaseListener</phase-listener>
</lifecycle>
<validator>
<validator-id>validaComboRequerido</validator-id>
<validator-class>mx.udg.cgti.seguridad.validator.ValidaComboRequerido</validator-class>
</validator>
<converter>
<converter-id>tipoUsuario</converter-id>
<converter-class>mx.udg.cgti.ln.convertidor.TipoUsuarioConverter</converter-class>
</converter>
<converter>
<converter-id>Usuario</converter-id>
<converter-class>mx.udg.cgti.ln.convertidor.UsuarioConverter</converter-class>
</converter>
<converter>
<converter-id>Rol</converter-id>
<converter-class>mx.udg.cgti.ln.convertidor.RolConverter</converter-class>
</converter>
<converter>
<converter-id>Permiso</converter-id>
<converter-class>mx.udg.cgti.ln.convertidor.PermisoConverter</converter-class>
</converter>
<converter>
<converter-id>UnidadOrganizacional</converter-id>
<converter-class>mx.udg.cgti.ln.convertidor.UnidadOrganizacionalConverter</converter-class>
</converter>
</faces-config>
Apparently you've another version of exactly the same class somewhere in the classpath which got precedence in classloading over the one included in the WAR.
That can be inside the /lib folder of the server itself, or inside the /lib or /lib/ext folders of the installed JRE which is used by the server.