Bild in derby DB speichern

markai

Aktives Mitglied
Ich würde gerne meinen User(-Entities) die Möglichkeit geben ein Bild hochzuladen (in die derby DB zu speichern). Dazu habe ich folgendes Attribut definiert...
Java:
@Entity @Table(name="Users")
public class User implements Serializable {
    //...
    @Column @Lob
    private Byte[] photo;
//Getter, Setter
... und daraus dann meine JSF-pages generiert. Nun weiß ich aber nicht wie ich ein Bild in dieses Byte[] bekommen soll.
Hab mal gegoogelt wie man die Sache am besten angeht. Mir ist aufgefallen dass viele dafür ein eigenes Servlet schreiben. Bin mir aber nicht sicher ob ich das mit den Servlets überhaupt verstanden hab, darum versuch ichs mal zu erklären:
In der web.xml werden url-Pattern auf das jeweilige Servlet gematcht. Standardmäßig wird (zumindest bei mir) das Faces-Servlet als Controller verwendet. Will ich nun zb. Bilder hochladen kann/muss ich mein eigenes Servlet erstellen, welches dann verwendet wird wenn zb. "img/*" in der URL vorkommt.

Wl. ist das der größte Blödsinn. Kann mir nicht vorstellen dass das nicht einfacher geht, also bitte korrigiert mich. Gibt doch sicher einen einfacheren Weg Bilder in meine DB zu speichern?
 

JimPanse

Bekanntes Mitglied
Eine Möglichkeit wäre eine Komponenten-Bibliothek einzusetzen z.b. Tomahawk
FileUpload

Java:
@ManagedBean
@RequestScoped
public class Bean {
    private UploadedFile uploadedFile;

    public void submit() throws IOException {
        byte[] bytes = uploadedFile.getBytes();
       //speichern
    }

    public UploadedFile getUploadedFile() {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFile uploadedFile) {
        this.uploadedFile = uploadedFile;
    }
}

Die Frage ist eher ob es Sinn macht Bilder in eine Datenbank zu speichern...
 

markai

Aktives Mitglied
Wo soll ich denn meine Bilder sonst speichern? Hätte gerne dass meine Benutzer für ihr jeweiliges Benutzerkonto ein Icon hochladen können und sehe keine andere Möglichkeit als dieses in eine DB zu speichern.
 

turtle

Top Contributor
Hab diesen Code-Snippet gefunden, zwar nicht ausprobiert müsste aber funktionieren:

Java:
   PreparedStatement ps;
    ps = con.prepareStatement("insert into employee(name,photo) " + "values(?,?)");
    ps.setString(1, "Duke");

    Blob blob = con.createBlob();
    ImageIcon ii = new ImageIcon("duke.png");

    ObjectOutputStream oos;
    oos = new ObjectOutputStream(blob.setBinaryStream(1));
    oos.writeObject(ii);
    oos.close();
    ps.setBlob(2, blob);
    ps.execute();
    blob.free();
    ps.close();
 

JimPanse

Bekanntes Mitglied
Wo soll ich denn meine Bilder sonst speichern? Hätte gerne dass meine Benutzer für ihr jeweiliges Benutzerkonto ein Icon hochladen können und sehe keine andere Möglichkeit als dieses in eine DB zu speichern.

Wie wäre es direkt im xampp und anstatt dem byte array die relativen pfad information zu dem Bild?

Dann ersparst du der Datenbank - eventuelle größere byte-felder auslesen zu müssen - gerade bei größen Übersichtslisten (Benutzer + Bilder) eventuell deine DB in die Knie zwingen könnte.
 

markai

Aktives Mitglied
Danke für eure Tipps. Das Icon soll nicht besonders groß sein, würde es also schon ganz gerne in meiner DB haben. (Verwende übrigens den Glassfish Server). Versuche gerade mit dem FileUploader von Primefaces zurechtzukommen, allerdings sagt mir mein Compiler immer dass er die Methode nicht findet. Habe das Beispiel aber von der Primefaces HP entnommen, und da scheint es zu funktionieren...

Hier meine imageUpload.xhtml
[XML]
<ui:composition template="/WEB-INF/template/Template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">

<ui:define name="content">

<h:form enctype="multipart/form-data">

<p:fileUpload fileUploadListener="#{imageUpload.handleFileUpload}"
mode="advanced"
update="messages"
sizeLimit="100000"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>

<p:growl id="messages" showDetail="true"/>

</h:form>

</ui:define>
</ui:composition>
[/XML]

... und meine ImageUpload bean

Java:
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean
@SessionScoped
public class imageUpload implements Serializable {
    
    public void handleFileUplaod(FileUploadEvent event) {
            FacesMessage msg = new FacesMessage("Succesfull", event.getFile().getFileName() + " is uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

Was mache ich denn falsch??
 

JimPanse

Bekanntes Mitglied
Danke für eure Tipps. Das Icon soll nicht besonders groß sein, würde es also schon ganz gerne in meiner DB haben. (Verwende übrigens den Glassfish Server). Versuche gerade mit dem FileUploader von Primefaces zurechtzukommen, allerdings sagt mir mein Compiler immer dass er die Methode nicht findet. Habe das Beispiel aber von der Primefaces HP entnommen, und da scheint es zu funktionieren...

Welche Methode findet der Compiler nicht? Poste doch einfach mal den Stacktrace.
 

markai

Aktives Mitglied
Die handleFileUpload Methode wird nie aufgerufen.
Java:
<p:fileUpload fileUploadListener="#{imageUpload.handleFileUpload}"  ...

Hab keinen Stacktrace, schon der Compiler sagt mir dass es die Methode nicht gibt (was er aber auch bei anderen Methoden macht die später doch noch aufgerufen werden). Wenn ich auf upload klicke passiert einfach nichts :( Hab mir gedacht dass es daran liegt das die Methode ein Event erwartet das ich nicht mitübergebe, aber bei der Primefaces Demo wirds auch so gemacht. (Ohne parameter funktionierts aber auch nicht)

@turtle: wenn ich jemals soweit komme dass ich meine methode aufrufen kann werde ich deinen Code ausprobieren...
 

markai

Aktives Mitglied
Ja da hab ich mich vertippt. Die Methode heißt aber so. Codecompletion funktioniert komischerweise, aber dann muss ich immer ein Event mitübergeben, was ja in der Demo so nicht gemacht wird...
 

JimPanse

Bekanntes Mitglied
Die handleFileUpload Methode wird nie aufgerufen.
Java:
<p:fileUpload fileUploadListener="#{imageUpload.handleFileUpload}"  ...

Hab keinen Stacktrace, schon der Compiler sagt mir dass es die Methode nicht gibt

äääh???? Du meinst den Editor oder? Wenn mein Compiler eine Klasse oder Methode nicht findet kann dieser nicht compilieren...


aber dann muss ich immer ein Event mitübergeben, was ja in der Demo so nicht gemacht wird...

Du musst bei JSF-Eventhandlern nie das konkrete event mitgeben.

Kontrollier mal ob in deinem Template.xhtml <h:head> verwendet wird (beliebter fehler) bzw. ob auch alle JScript's geladen worden sind in den head der Seite
 

markai

Aktives Mitglied
Editor? Dachte immer der Compiler überprüft das... Was du mit der Template.xhtml meinst versteh ich nicht. <h:head... wird in meinem Template verwendet. Darf ich das nicht?
Hier meine Template.xhtml:

Java:
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:lang="http://java.sun.com/jsf/composite/components/languageUtils">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <h:outputStylesheet library="css" name="cssLayout.css"/>
        <h:outputStylesheet library="css" name="default.css"/>
        <title>Title</title>
    </h:head>

    <h:body>
        <p:growl id="growl" showDetail="true" sticky="false"/>
        <div>
            <div id="top">
                <ui:insert name="top">top</ui:insert>
            </div>
            <div id="menu">
                <ui:insert name="home"><lang:selector locales="de,en"/></ui:insert>
            </div>
        </div>
        <div id="content" class="center_content">
            <ui:insert name="content">Content</ui:insert>
        </div>
        <div id="bottom">
            <ui:insert name="bottom">bottom</ui:insert>
        </div>
    </h:body>
</html>
 

markai

Aktives Mitglied
Ok jetzt hab ich auch eine Exception bekommen:

Java:
WARNING: /pages/cilab/imageUpload.xhtml @18,53 fileUploadListener="#{imageUpload.handleFileUpload}": Method not found: at. ....controller.imageUpload@994358e.handleFileUpload(org.primefaces.event.FileUploadEvent)
javax.el.MethodNotFoundException: /pages/cilab/imageUpload.xhtml @18,53 fileUploadListener="#{imageUpload.handleFileUpload}": Method not found: ....controller.imageUpload@994358e.handleFileUpload(org.primefaces.event.FileUploadEvent)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109)
	at org.primefaces.component.fileupload.FileUpload.broadcast(FileUpload.java:279)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:759)
	at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:935)
	at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
	at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:77)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
	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 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
	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:722)
 

JimPanse

Bekanntes Mitglied
<h:head> ist richtig.

Java:
@ManagedBean
@SessionScoped
public class imageUpload implements Serializable {
    
    public void handleFileUplaod(FileUploadEvent event) {
            FacesMessage msg = new FacesMessage("Succesfull", event.getFile().getFileName() + " is uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

Schreib mal den Klassennamen groß -> ImageUpload.
 

markai

Aktives Mitglied
Heute vertipp ich mich ständig... Die Exception kam wohl auch wegen eines Tippfehlers :/ Hab nun endlich mein byte[] wo mein Bild drin ist. Jetzt muss ich dieses nur mehr in meinen User übergeben. Dazu hab ich mir folgendes gedacht:

In meiner ImageUpload Klasse wandle ich das Bild in ein byte[] um:
Java:
@Named("imageUpload")
@RequestScoped
public class ImageUpload implements Serializable {

    private UploadedFile uploadedFile;
    private byte[] fileContentsByteArray;
...

Dann hätte ich gerne in meinem UserController dieses byte[]. Dazu mache ich:
Java:
@ManagedBean(name = "userController")
@SessionScoped
public class UserController implements Serializable {

    private User current;
    private DataModel items = null;
    @EJB
    private UserFacade ejbFacade;

    @Inject
    private ImageUpload imageUploader;

Scheinbar kann ich meinen imageUploader aber nicht in meinen Controller injezieren, denn wenn ich in der Methode welche meinen User erzeugt folgendes mache:
Java:
    public String create() {
        try {

            current.setPhoto(imageUploader.getFileContentsByteArray());

            if(ValidationUtil.isValid(current)){
            getFacade().create(current);
            JsfUtil.addSuccessMessage("UserCreated");
            return prepareCreate();
            ...
... liefert mir der getter für mein byte[] null zurück.

Mir ist nur diese Lösung eingefallen, diese funktioniert aber nicht :( Leider schnall ich dieses Java EE noch nicht so ganz...
 

JimPanse

Bekanntes Mitglied
Du kannst eine JSF-Beans in einer anderen JSF-Bean nur injekten wenn der Scope gleich oder größer ist und Session ist eindeutig größer als Request d.h. Mach es einfach anders herum ;-)

Du injektes den UserController in der ImageUploadBean.

Greetz
 

markai

Aktives Mitglied
Vielen Dank! Es funktioniert :D Ist eigentlich eh logisch dass man keine RequestScoped bean in eine SessionScoped bean injecten kann... Hab mal beide beans mit SessionScope versucht. Das hat nicht geklappt, erst mit ApplicationScope ging es. Werd morgen mal überlegen ob ich den Spieß umdrehe - wie du es mir empfohlen hast - aber jetzt freu ich mich erstmal dass in meiner Datenbank mal was anderes als null ankommt :toll:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Dimax Bild speichern und auf JSP zeigen Web Tier 74
M JSF Bild aus DB in JSF darstellen Web Tier 7
R Bild aus Datenbank ausgeben/anzeigen Web Tier 5
5 Bild Pfad Servlet Web Tier 2
V Bild aus ArrayList via h:graphicImage anzeigen lassen Web Tier 4
P Bild hochladen Web Tier 9
D Servlet Bild als JPG darstellen - nur alternativer Text Web Tier 16
T Bild durch anderes Bild ersetzen mit Servlet Web Tier 3
J h:graphicImage lädt kein Bild. Web Tier 3
D JSF Template mit Bild Web Tier 3
R Anzeigeproblem von Bild in Jsp Web Tier 5
R Status als Bild anzeigen lassen. Wie? Web Tier 15
S Bild hochladen mit JSP - Parameter übergeben Web Tier 4
W Servlet SPEICHERN UNTER-Dialog für mehrere Dateien Web Tier 4
M JSF Website automatisch als PDF speichern Web Tier 1
C GWT - Properties auf Serverseite speichern Web Tier 2
S JSP Erzeugten JSP HTML-Quelltext in html-Datei speichern Web Tier 4
H text in formfelder speichern Web Tier 3
B String aufteilen und in Variablen speichern. Web Tier 18
H selectfeld zustand speichern Web Tier 6
E Servlet zum speichern einer Datei in einer Datenbank Web Tier 3
I Ajax DOM speichern Web Tier 27
M Dateien im Verzeichnis meines Webprojektes speichern Web Tier 4
S JSF Fo_rmulardaten in DB mittels H_i_bernate speichern Web Tier 3
G Daten von ablaufenden Sessions speichern? Web Tier 3

Ähnliche Java Themen

Neue Themen


Oben