Bonjour,

j'ai développé un petit site qui gère l'enregistrement et la récupération d'images en base de données.

Ma table est la suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `portfolio` (
  `ID` BIGINT(20) NOT NULL,
  `DESCRIPTION` VARCHAR(255) DEFAULT NULL,
  `NAME` VARCHAR(255) DEFAULT NULL,
  `URL` VARCHAR(255) DEFAULT NULL,
  `CONTENTTYPE` VARCHAR(255) DEFAULT NULL,
  `FILENAME` VARCHAR(255) DEFAULT NULL,
  `IMAGEFILE` LONGBLOB,
  `IMAGESIZE` BIGINT(20) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
La classe entity associée est la suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Entity
public class Portfolio implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    @Id
    @GeneratedValue(generator = "Portfolio_Gen")
    @TableGenerator(name = "Portfolio_Gen", 
            table = "ID_GEN", 
            pkColumnValue = "Portfolio_Gen", 
            valueColumnName = "GEN_VAL", 
            pkColumnName = "GEN_NAME",
            initialValue=0, 
            allocationSize = 20)
    private Long id;
    private String name;
    private String description;
    private String url;
    @Embedded
    private Image image;
 
    //Getters et setters
 
}
avec une classe image :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
@Embeddable
@Access(AccessType.FIELD)
public class Image implements Serializable {
 
    private static final long serialVersionUID = 1L;
    private byte[] imageFile;
    private String fileName;
    private long imageSize;
    private String contentType;
 
    //Getters et setters
 
}
Pour m'entraîner avec les composites components, j'essaye d'afficher une image avec diverses infos la concernant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!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:composite="http://java.sun.com/jsf/composite"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:a4j="http://richfaces.org/a4j">
 
    <composite:interface>
        <composite:attribute name="portfolio"
                             required="true"/>
        <composite:attribute name="createContentAction"
                             method-signature="void createContent(java.io.OutputStream,java.lang.Object) throws java.io.IOException"
                             required="true"/>
        <composite:attribute name="sitePrompt" 
                             default="#{cc.resourceBundleMap.sitePrompt}"/>
        <composite:attribute name="urlPrompt" 
                             default="#{cc.resourceBundleMap.urlPrompt}"/>
        <composite:attribute name="timeStamp" required="true"/>
    </composite:interface>
 
    <composite:implementation>
        <div>
            <a4j:mediaOutput id="portfolioImage"
                             element="img"
                             mimeType="#{cc.attrs.portfolio.image.contentType}"
                             createContent="#{cc.attrs.createContentAction}"
                             value="#{cc.attrs.portfolio.id}"
                             cacheable="false">
                <f:param value="#{cc.attrs.timeStamp}" name="time" />
            </a4j:mediaOutput>
            <p>
                <h:outputText styleClass="gras" 
                              value="#{cc.attrs.sitePrompt}"/>
                <h:outputText value="#{cc.attrs.portfolio.name}"/>
            </p>
            <p>
                <h:outputText styleClass="gras" 
                              value="#{cc.attrs.urlPrompt}"/>
                <h:outputText value="#{cc.attrs.portfolio.url}"/>
            </p>
        </div>
    </composite:implementation>
</html>
Enfin, la page qui doit l'afficher :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
<?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:h="http://java.sun.com/jsf/html"
      xmlns:myComp="http://java.sun.com/jsf/composite/components/portfolio">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <myComp:Portfolio portfolio="#{portfolioTest.portfolio}" createContentAction="#{portfolioTest.paint}" timeStamp="#{portfolioTest.timeStamp}"/>
    </h:body>
</html>
ainsi que le managedBean :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@ManagedBean
@RequestScoped
public class portfolioTest implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    @EJB
    private CrudService<Portfolio> crudService;
 
    public portfolioTest() {
    }
 
    public Portfolio getPortfolio() {
        return crudService.find((long) 2);
    }
 
    public void paint(OutputStream stream, Object object) throws IOException {
        Portfolio portfolio = crudService.find(object);
        stream.write(portfolio.getImage().getImageFile());
        stream.close();
    }
    public long getTimeStamp() {
        return System.currentTimeMillis();
    }
 
}
Le soucis que j'ai c'est que ça ne fonctionne pas.

Lorsque que je lance la page web qui doit m'afficher le composite component, j'ai l'erreur suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
ATTENTION: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
javax.faces.FacesException: Unable to resolve composite component from using page using EL expression '#{cc.attrs.createContentAction}'
	at com.sun.faces.facelets.tag.TagAttributeImpl$AttributeLookupMethodExpression.invoke(TagAttributeImpl.java:444)
	at org.richfaces.resource.MediaOutputResource.encode(MediaOutputResource.java:62)
	at org.richfaces.resource.UserResourceWrapperImpl.encode(UserResourceWrapperImpl.java:188)
	at org.richfaces.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:222)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:591)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
	at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)
Je précise que si je supprime la balise a4j:mediaOutput les informations (name et url) sont bien récupérées en bases.

J'ai pas trouvé d'utilisation de a4j:mediaOutput dans un composite component sur le web, donc la je sèche carrément d'où ce message sur le forum.

Merci d'avance pour votre aide.