将旧JSP迁移到Facelet(未实例化托管bean)

时间:2016-04-01 08:53:55

标签: jsf-2 facelets composite-component tomee

我使用旧的时尚JSP scriptlet代码,我决定尝试使用Facelets并迁移我的应用程序。我已经不喜欢一些东西了(比如必须更改设计师给我的一些HTML5标签的额外工作,关闭它们等)但是好处似乎值得。我在迁移中发现了一些问题,基本上我正在尝试定义composite component并传递List<T extends BasicData>来显示。

我正在使用Netbeans 8.0.2Apache Tomcat 8.0.3.0(J2EE 7),JDK 1.8。我正在阅读Java Server Faces - Introduction by example以获得帮助和示例。

1)我不确定我是否在 Maven 中包含了正确的依赖项,或者我是否在库中包含了重复的功能。这是最低限度吗? (考虑到我可能会使用一些JSTL)

<dependencies>
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.faces</groupId>
    <artifactId>javax.faces-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <!-- This is the Mojarra Implementation of JSF -->
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.2.8-02</version>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.1.0-b03</version>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.1.0-b03</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
</dependency>

<dependency>
    <groupId>com.sun.el</groupId>
    <artifactId>el-ri</artifactId>
    <version>1.0</version>
</dependency>

2)由于 JSF 2.0 ,我不应该在web.xml中需要以下片段。但是,当我省略它时,我没有得到JSF渲染,我只获得未经处理的XML。我做错了什么?

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping> 

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

3)现在主要的问题是我的bean似乎没有实例化。一切都很好,除了bean传递总是null。实际上我可以传递任何数据类型(例如String而不是List)并且它永远不会抱怨(因为我传递的任何内容始终是null而Netbeans显然没有检测到它编译时间)。

的index.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:util="http://java.sun.com/jsf/composite/util"
                template="template.xhtml">
    <ui:define name="content">
        <util:visualisationList
            elementList="#{visualisationListController.elements}"/>
    </ui:define>
</ui:composition>

visualisationListController.java

    @Named(value = "visualisationListController")
    @Dependent
    public class VisualisationListController <T extends BasicData> implements Serializable {

        private List<T> elements;
        /**
         * Creates a new instance of visualisationList
         */
        public VisualisationListController() {
           // This is for testing, eventually I would like to get this information from a DB
            System.out.println("constructor");
            elements = new ArrayList<>();
            ComplexData cd = new ComplexData(); // ComplexData EXTENDS BasicData
            cd.setName("ELEMENT 1");
            elements.add((T)cd);
            cd = new ComplexData();
            cd.setName("ELEMENT 2");
            elements.add((T)cd);
        }

        public List<T> getElements() {
            return elements;
        }

        public void setElements(List<T> elements) {
            this.elements = elements;
        } 
    }

visualisationList.xhtml (这会呈现,但列表为null,因此不打印任何内容)

    <!DOCTYPE html>
    <html lang="en"
          xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:cc="http://xmlns.jcp.org/jsf/composite"
          xmlns:c="http://java.sun.com/jsp/jstl/core">

        <!-- INTERFACE -->
        <cc:interface>
            <cc:attribute name="elementList" type="java.util.List" required="true" shortDescription="The list of objects to be displayed"/>
        </cc:interface>

        <!-- IMPLEMENTATION -->
        <cc:implementation>
                    <ul>
                        <c:forEach items="#{cc.attrs.elementList}" var="element">
                            <li>
                                #{element.name}
                            </li>
                        </c:forEach>
                    </ul>
        </cc:implementation>
    </html>

我从未读过我需要beans.xml建议herethis post也没有给我提供线索。该bean应该被自动实例化。为了做进一步的测试,我尝试了前面提到的book中的第一个简单示例,我的bean也没有实例化。我从书中了解到该对象应该自动实例化。

如果我处理或创建List的方式出现错误,我还尝试使用不太复杂的数据(仅String),使用@SessionScoped和删除c:forEach,它也不起作用。

修改

由于(再次)BalusC指针,问题得到解决。我必须从不同的来源获取信息,所以,为了方便起见,我编写了我在下面采取的步骤。但是,我的问题仍然不明确(1): 根据{{​​3}}页面,我只需要包含一个Maven依赖项。但是,这样做时,我收到以下错误消息:

An Error Occurred:

Could not get component metadata for visualisationList.xhtml. Did you forget to specify <composite:interface>?

viewId=/index.xhtml
location= ...

我尝试了几件事,包括JSF info中的步骤,但未成功。如果我包含某些库,我会得到:

javax.servlet.ServletException
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

java.lang.NullPointerException
    java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    java.util.concurrent.ConcurrentHashMap.putIfAbsent(ConcurrentHashMap.java:1535)

对我来说唯一有用的,虽然我不确定为什么,但是要包括依赖:

    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.faces</artifactId>
        <version>2.2.8-02</version>
        <scope>runtime</scope>
    </dependency>

(当然还有javaee-web-api 6.0)

只有这样,我才能得到我从一开始就期待的结果。但是,我不明白为什么必须包含这种依赖性,如果TomEE被禁止提供它。另外,我不确定这意味着当我读到EE 6应该只运行到2.1时我会使用v.2.2。最后,我必须为此创建一个beans.xml,我不知道为什么 - 这只适用于JSF版本&lt; = 2.1?

我决定改变TOMCAT到NETBEANS的步骤

  1. 下载TomEE。在Netbeans服务器部分中安装和配置它。 (here
  2. 编辑TomEE server.xml并更改所有端口以避免与我的旧Tomcat冲突。
  3. 在server.xml中,从连接器中删除xpoweredByserver属性:

    Source

  4. 然后,在bin/catalina.bat更改:

    :noJuliConfig
    set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%"
    ...
    :noJuliManager
    set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%"
    

    为:

    :noJuliConfig
    set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%
    ... 
    :noJuliManager
    set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%
    

    Source

  5. 然后右键单击项目 - 属性 - 运行。将服务器更改为TomEE和Java EE版本到#34; Java EE 6 Web&#34; (因为当前版本的TomEE只接受JEE 1.6)。 pom.xml中的依赖关系必须相应地更改为版本6:

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version> <!-- 7.0 (JSF 2.2) or 6.0 (JSF 2.0/2.1) -->
        <scope>provided</scope>
    </dependency>
    ....
    <artifactItem>
         <groupId>javax</groupId>
         <artifactId>javaee-endorsed-api</artifactId>
         <version>6.0</version>
         <type>jar</type>
     </artifactItem>
    

    ...

  6. 现在TomEE应该运行并运行Netbeans的应用程序。

0 个答案:

没有答案