Java EE + primefaces + jboss - upload plików na serwer

0

Cześć,

piszę sobie mały webowy projekt w Javie i mam ogromny problem z wysyłaniem plików na serwer. Dokładnie to wrzucanie obrazków przy dodawaniu artykułów na stronie. Szukałem w internetach parę godzin i z żadnych poradników ani for nie byłem w stanie skonstruować niczego działającego.

Zastanawiam się też czy wrzucanie tych obrazków do folderu WebContent/resources/... będzie odpowiednim rozwiązaniem? Jak nie to gdzie je wrzucać i jak je potem wyświetlić na stronie(jeżeli nie z resources bo stąd umiem).

**Bardzo, bardzo **proszę o pomoc, ja już z tym kompletnie wymiękam.

Chcę taki formularz:

<h:form>
	[...]
	<p:fileUpload  mode="simple" skinSimple="true"/>
	<p:commandButton value="Zapisz" action="#{adminArticles.addArticle()}" />
</h:form>

Oraz taki adminArticles.java

private UploadedFile uploadedFile;

 public String addArticle() throws IOException {
	Article article = new Article();
	article.setTitle(title);
	article.setContent(content);
	article.setDate(new Date());

        **Magiczny kod do zapisu pliku na serwer**

	article.setImg(**Tutaj bym chciał nazwę pliku z rozszerzeniem zapisać do bazy**);
	article.setUser(UserControl.getActualUser());

	try {
		articleDAO.create(article);
	} catch (Exception e) {
		e.printStackTrace();
		ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd podczas zapisu.", null));
		return null;
	}
	return "/pages/admin/articlesList";
}
0

Plik zapisuj w systemie plików, a w bazie tylko jego nazwę. Dodatkowo zmień nazwę pliku na wypadek gdyby ktoś wpisał jakieś chińskie znaki, np. haszując ją.
Plik możesz zapisać jakoś tak:

<p:fileUpload value="#{fileUploadView.uploadedFile}" mode="simple" 
              allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />

FileUploadView.java

Files.copy( uploadedFile.getInputstream(), 
            Paths.get( destination_path, uploadedFile.getFileName()));

a wyświetlać tak:

<p:graphicImage value="#{someView.imgfile}" />

SomeView.java:

import org.primefaces.model.DefaultStreamedContent
imgfile= new DefaultStreamedContent( new FileInputStream("/path/img.png"));

Nazwę pliku możesz możesz zhashować tak:

import org.apache.commons.codec.digest.DigestUtils;
String newfilename = DigestUtils.md5Hex( uploadedFile.getFileName());
0

Dzięki za odpowiedź, ale nadal mam problem. Niestety uploadedFile jest ciągle nullem, przez co mam nullPointerException, inne pola normalnie przekazują wartości do zmiennych(np. tytuł czy treść), a plik za nic nie chce.

articleAdd.xhtml

 <h:form>
	<p:panel id="panel" header="Form" style="margin-bottom:10px;">
		<h:panelGrid columns="2" cellpadding="5">
			<p:outputLabel for="login" value="Tytuł:" />
			<p:inputText id="login" required="true" value="#{adminArticles.title}" />

			<h:outputLabel for="password" value="Treść:" />
			<p:editor id="password" required="true" value="#{adminArticles.content}" />

			<p:fileUpload value="#{adminArticles.uploadedFile}" mode="simple" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />

			<p:commandButton value="Zapisz" action="#{adminArticles.addArticle()}" />


		</h:panelGrid>
	</p:panel>
</h:form>

adminArticles.java


private UploadedFile uploadedFile;

	public UploadedFile getUploadedFile() {
		return uploadedFile;
	}

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

	public String addArticle() throws IOException {
		Article article = new Article();
		article.setTitle(title);
		article.setContent(content);
		article.setDate(new Date());		
		
		Files.copy(uploadedFile.getInputstream(), FileSystems.getDefault().getPath( "/lolek/", uploadedFile.getFileName()));
		
		article.setImg(uploadedFile.getFileName());
		article.setUser(UserControl.getActualUser());

		try {
			articleDAO.create(article);
		} catch (Exception e) {
			e.printStackTrace();
			ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd podczas zapisu.", null));
			return null;
		}
		return "/pages/admin/articlesList";
	}

Konsola, po kliknięciu przycisku "wyślij":

 
16:59:19,948 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-44) #{adminArticles.addArticle()}: java.lang.NullPointerException: javax.faces.FacesException: #{adminArticles.addArticle()}: java.lang.NullPointerException
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at security.SecurityCheckFilter.doFilter(SecurityCheckFilter.java:126)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:792)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	... 39 more
Caused by: java.lang.NullPointerException
	at admin.adminArticles.addArticle(adminArticles.java:120)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at javax.el.ELUtil.invokeMethod(ELUtil.java:300)
	at javax.el.BeanELResolver.invoke(BeanELResolver.java:415)
	at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:285)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
	at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
	at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
	... 40 more

16:59:19,949 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (default task-44) javax.faces.el.EvaluationException: java.lang.NullPointerException
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at security.SecurityCheckFilter.doFilter(SecurityCheckFilter.java:126)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:792)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
	at admin.adminArticles.addArticle(adminArticles.java:120)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at javax.el.ELUtil.invokeMethod(ELUtil.java:300)
	at javax.el.BeanELResolver.invoke(BeanELResolver.java:415)
	at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:285)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
	at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
	at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
	... 40 more
0

Przykład ze strony Primefaces:
http://www.primefaces.org/showcase/ui/file/upload/basic.xhtml

 <h:form enctype="multipart/form-data">
    <p:growl id="messages" showDetail="true" />
 
    <p:fileUpload value="#{fileUploadView.file}" mode="simple" skinSimple="true"/>
 
    <p:commandButton value="Submit" ajax="false" actionListener="#{fileUploadView.upload}" />
</h:form>

zwróć uwagę na enctype="multipart/form-data" i ajax=false

0

Super, teraz wysyłanie działa :)
Dzięki ogromne, ale zaś mam problem z wyświetleniem tego :D

22:39:06,856 SEVERE [org.primefaces.application.resource.StreamedContentHandler] (default task-61) Error in streaming dynamic resource. java.io.FileNotFoundException: photos (Access is denied)

Ścieżka jest dobra, nazwa pliku przekazana dobra, java widzi plik - bo jak zmienię ścieżkę na jakąkolwiek niepoprawną to wywala wyjątek :) Strona się ładuje ale brak obrazka, tylko sama ikonka niezaładowanego obrazka. Niby brak dostępu, tylko jak to zmienić? Przyp. mam Windowsa 10 :)

 public DefaultStreamedContent obrazek(String name) throws FileNotFoundException {
	System.out.println(name);
	return new DefaultStreamedContent( new FileInputStream("photos/" + name));
}
<p:graphicImage value="#{articleListBB.obrazek(article.img)}" />

Ciekawe jest też ta metoda obrazek() wywołuje się 2 razy - wyświetla 2 razy nazwę pliku, lecz ten błąd jest wyświetlany w konsoli tylko raz.

0

Możliwości są dwie, albo podajesz złą ścieżkę albo nie masz uprawnień.
Daj dla pewności 'article.img' w html w apostrofy i pełną ścieżkę do photos, będziesz miał przynajmniej pewność

0

To na pewno kwestia uprawnień, bo jak podaje inną ścieżkę to dostaję java.io.FileNotFoundExceptio, a jak podaje pełną to jest to co powyżej.
Tak więc jak dodać te uprawnienia dla Jboss-a? :O
Bo w samym Windowsie, w właściwościach folderu nadałem pełne uprawnienia wszystkim(swoją drogą nie wiedziałem że w systemie tym istnieje kilkadziesiąt userów/grup :O) i błąd nadal występuje - plik oczywiście również ma takie same - pełne uprawnienia.

0

"Na moim komputerze działa" (windows7)

<p:graphicImage value="#{image.obrazek('obrazek.gif')}" />
@Named
@RequestScoped
public class Image {

    public DefaultStreamedContent obrazek(String name) 
            throws FileNotFoundException 
    {
        return new DefaultStreamedContent(new FileInputStream("D:\\obrazki\\" + name));
    }

}

Przyznaj, nie chciało ci się sprawdzić z tymi apostrofami, nie?

0

W taki sposób na sztywno u mnie też działa. Próbowałem z apostrofami, lecz przekazywałem w parametrze 'article.img' - a to nie działa.
Gdy chcę nazwę pliku z bazy to funkcja obrazek() zostaje wywołana 3 razy, dwukrotnie poprawnie, z dobrym parametrem, lecz za trzecim razem jest on pusty... więc ścieżka jest niekompletna. Dodam że jak korzystam z reszty informacji o artykule, np. article.content to są one normalnie bez problemu wyświetlane.

00:18:12,528 INFO  [stdout] (default task-25) siec_kin.jpg
00:18:12,528 INFO  [stdout] (default task-25) C:\Users\Sasi\EAP-7.0.0\bin\photos\siec_kin.jpg // tutaj jest ok
00:18:12,529 INFO  [stdout] (default task-25) siec_kin.jpg
00:18:12,529 INFO  [stdout] (default task-25) C:\Users\Sasi\EAP-7.0.0\bin\photos\siec_kin.jpg // tutaj też jest ok
00:18:12,543 INFO  [stdout] (default task-26) 
00:18:12,543 INFO  [stdout] (default task-26) C:\Users\Sasi\EAP-7.0.0\bin\photos\ // a tu za trzecim razem coś zjada nazwę pliku, i nie wiem czemu, akurat to ostatnie wywołanie jest tym "wyświetlanym" 
0

No to nie wiem :p
możesz też zrobić servlet albo jax-rs, akurat mam na dysku to Ci skopiuje:

servlet:

@WebServlet("/images_servlet")
public class ImagesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException 
    {
        String filename = request.getParameter("imgname");
        Path path = Paths.get("d:/randomImages", filename);
        File file = path.toFile();
        response.setHeader("Content-Type", getServletContext().getMimeType( filename));
        response.setHeader("Content-Length", String.valueOf( file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
        Files.copy( path, response.getOutputStream());
    }

}

jax-rs:

@javax.ws.rs.Path("/images_jaxrs")
public class ImageService {
    
	@GET
	@javax.ws.rs.Produces({"image/jpeg, image/gif, image/png"})
	public Response getFile( @QueryParam("imgname") String imgname) {
            Path path = Paths.get("d:/randomImages", imgname);
            Response.ResponseBuilder response = Response.ok( path.toFile());
            response.header("Content-Disposition", "inline; filename=\"" + imgname + "\"");
            return response.build();
	}
}
<!-- servlet -->
<img src="images_servlet?imgname=obrazek.gif" />
<!-- jax-rs -->
<img src="webresources/images_jaxrs?imgname=obrazek.gif" />

albo odpowiednio używając facelets:

<!-- servlet -->
<h:graphicImage value="images_servlet?imgname=obrazek.gif" />
<!-- servlet -->
<h:graphicImage value="webresources/images_jaxrs?imgname=obrazek.gif" /> 

1 użytkowników online, w tym zalogowanych: 0, gości: 1