0

I have a page class defined as below (I've removed all custom fields).

public class TwoColPage extends PageImpl {
   //TODO: metadata fields
}

In my JSP I have

<jsp:useBean id="pageModel" type="org.company.models.TwoColPage" scope="request"/>

When I run the page, I get the following exception

Stacktrace: org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:574) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) javax.servlet.http.HttpServlet.service(HttpServlet.java:622) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) root cause

java.lang.ClassCastException: org.dd4t.contentmodel.impl.PageImpl cannot be cast to org.company.models.TwoColPage org.apache.jsp.WEB_002dINF.views.pages.two_002dcolumn_002dpage_jsp._jspService(two_002dcolumn_002dpage_jsp.java:120) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) javax.servlet.http.HttpServlet.service(HttpServlet.java:622) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Should I be extending/implementing a different base class/interface or is there something else I am missing here?

I see that the getPage method of PageFactory returns interface Page, which PageImpl does implement (indirectly via GenericPage which is marked as deprecated)

2 Answers 2

1

This is fixed in dd4t-java version 2.0.6. Any class you want to deserialize page data into must implement the org.dd4t.contentmodel.Page interface or extend the PageImpl class:

public class MyPageImpl implements Page {
    // Code here
}

The PageFactory class has two new methods:

<T extends Page> T getPage(final String uri, final Class<T> pageModel ) throws FactoryException;

<T extends Page> T findPageByUrl (String url, int publicationId, Class<T> pageModel) throws FactoryException;

So deserialising your custom objects goes like this:

MyPageImpl page = pageFactory.getPage("tcm:x-x-64", MyPageImpl.class);

// OR

MyPageImpl page = pageFactory.findPageByUrl("/index.hml",7,MyPageImpl.class);
1

What it is trying to do here is downcasting, which is not really a good idea.

Simple Example:

  • PageImpl is Animal
  • TwoColPage is Cat
  • Not all Animals are Cats, so the compiler throws an error

The problem comes from this line in PageFactoryImpl

page = deserialize(pageSource, PageImpl.class);

It fixes the type of Page to PageImpl meaning the page (Super Class) cannot be cast to my page (Sub Class)

6
  • A better solution might be to wrap the PageImpl in your custom page class.
    – Quirijn
    Jun 10, 2016 at 10:17
  • Care to share an example? Thanks :) Jun 10, 2016 at 10:19
  • 1
    On second thought, it would be nice to overload the PageFactory.getPage method: PageFactory.getPage(String url, Type class) That would allow you to specify your own class to deserialize into.
    – Quirijn
    Jun 13, 2016 at 16:47
  • Yes. That is exactly what I was thinking actually. Where T implements Page interface Jun 13, 2016 at 16:53
  • See github.com/dd4t/dd4t-2-java/issues/64
    – Quirijn
    Jun 13, 2016 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.