o:graphicImage выбрасывает java.lang.IllegalArgumentException: несоответствие типов аргументов

Я не могу отобразить изображения из своей базы данных, они хранятся как байты, и я отображаю их так:

@Entity
@Table(name = "photograph", schema = "public")
public class Photograph{
    private PhotographId id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "diagnostic_id", nullable = false, insertable = false, updatable = false)
    private Diagnostic diagnostic;

    @Column(name = "photograph_content_type")
    private String photographContentType;

    @EmbeddedId
    @AttributeOverrides({
        @AttributeOverride(name = "diagnosticId", column = @Column(name  = "diagnostic_id", nullable = false)),
        @AttributeOverride(name = "photo", column = @Column(name = "photo", nullable = false)),
        @AttributeOverride(name = "photographDescription", column = @Column(name = "photograph_description", nullable = false, length = 100)) })
    public PhotographId getId() {
       return this.id;
    }

//Getters and Setters...
}

Это встраиваемый класс для ПК:

@Embeddable
public class PhotographId{
    @Column(name = "diagnostic_id", nullable = false)
    private Long diagnosticId;
    @Column(name = "photo", nullable = false)
    private byte[] photo;
    @Column(name = "photograph_description", nullable = false, length = 100)
    private String photographDescription;

//Getters and Setters...
}

Я могу хранить все изображения в базе данных без проблем. Проблема в том, когда я хочу показать их в p: dataTable следующим образом:

<p:dataTable id="dataTableLoadedPhotos"
                value="#{imageController.photographListUpdate}" var="image">
                <p:column headerText="Fotografías cargadas" width="110">
                    <o:graphicImage value="#{imageStreamer.getById(image.id)}"
                        alt="#{msgs['label.diagnostic.photograph.notFound']}" />
                </p:column>
            </p:dataTable>

Я использую стример на основе The BalusC Code: ImageServlet, и я попытался использовать o: graphicImage безуспешно, чего-то не хватает в коде mi:

@ManagedBean
@ApplicationScoped
public class ImageStreamer {

@EJB
private PhotographService photographService;

public byte[] getById(PhotographId id) {
    try {
        return photographService.getContent(id);
    } catch (ServiceException e) {
        FacesMessage mensaje = new FacesMessage(
                FacesMessage.SEVERITY_ERROR,
                "Error al buscar la fotografía "
                        + id.getPhotographDescription(), e.getMessage());
        FacesContext.getCurrentInstance().addMessage(null, mensaje);
    }
    return null;
}
}

У меня также есть управляемый компонент с @RequestScoped:

@ManagedBean
@RequestScoped
public class ImageController {

@EJB
private PhotographService photographService;

@ManagedProperty(value = "#{diagnosticDataManager}")
private DiagnosticDataManager diagnosticDataManager;

private List<Photograph> photographListUpdate = new ArrayList<Photograph>();
private Photograph selectedPhoto;

/**
 * 
 */
public ImageController() {
    diagnosticDataManager = new DiagnosticDataManager();
}

@PostConstruct
public void init() {
    if (diagnosticDataManager.getDiagnostic().getDiagnosticId() != null)
        photographListUpdate = photographService
                .findPhotosByDiagnostic(diagnosticDataManager
                        .getDiagnostic());

    for (Photograph photograph : photographListUpdate) {
        byte[] imageContent = org.apache.commons.codec.binary.Base64
                .decodeBase64(photograph.getId().getPhoto());
        ExternalContext ec = FacesContext.getCurrentInstance()
                .getExternalContext();
        ec.getSessionMap()
                .put(photograph.getId().toString(),
                        imageContent);
    }
}
// Getters and setters....
}

Поскольку я использую Maven, у меня есть каталог приложений, подобный этому:

src
|----main
     |----webapp
          |----images

У меня есть ошибка в моем server.log, и я не могу видеть изображение на странице, что отсутствует в моем коде?

20:22:43,687 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/patientdiagnostics].[Faces Servlet]] (http-localhost/127.0.0.1:8080-1) JBWEB000236: Servlet.service() for servlet Faces Servlet threw exception: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_79]
at org.omnifaces.resourcehandler.GraphicResource.getInputStream(GraphicResource.java:241) [omnifaces-2.0.jar:2.0]
at com.sun.faces.application.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:260) [jsf-impl-2.1.28.redhat-3.jar:2.1.28.redhat-3]
at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:125) [jboss-jsf-api_2.1_spec-2.1.28.Final-redhat-1.jar:2.1.28.Final-redhat-1]
at org.primefaces.application.resource.PrimeResourceHandler.handleResourceRequest(PrimeResourceHandler.java:74) [primefaces-5.1.jar:5.1]
at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:125) [jboss-jsf-api_2.1_spec-2.1.28.Final-redhat-1.jar:2.1.28.Final-redhat-1]
at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:125) [jboss-jsf-api_2.1_spec-2.1.28.Final-redhat-1.jar:2.1.28.Final-redhat-1]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:591) [jboss-jsf-api_2.1_spec-2.1.28.Final-redhat-1.jar:2.1.28.Final-redhat-1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:105) [primefaces-5.1.jar:5.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_79]

Я также пробовал что-то похожее на Отображение изображений блобов базы данных в внутри ;

1 ответ

Решение

Как указано в его документации и витрине,

В случае, если свойство является выражением метода, принимающим аргументы, каждый из этих аргументов будет преобразован в строковый параметр HTTP-запроса и обратно в реальные объекты с использованием преобразователей, зарегистрированных классом как доступные через Application.createConverter(Class), Итак, большинство стандартных типов, таких как Long уже неявно поддерживаются. Если по какой-либо причине вам нужно предоставить пользовательский объект в качестве аргумента, вам нужно явно зарегистрировать конвертер для него через @FacesConverter(forClass),

<o:graphicImage> преобразует все аргументы метода EL в строку и обратно, используя преобразователи JSF, зарегистрированные для класса типа аргумента. JSF уже имеет встроенные преобразователи, например, для Long типа, так вот почему они работают из коробки. Но ты там PhotographId введите в качестве аргумента метода EL и, по-видимому, для этого не зарегистрирован преобразователь JSF.

У вас есть 2 варианта:

  1. Не указывайте всю сущность в качестве аргумента. Вместо этого используйте его идентификатор, который в вашем случае просто Long,

    Например

    <o:graphicImage value="#{imageStreamer.getById(image.id.diagnosticId)}">
    

    И изменить getById() метод соответственно.

  2. Создать JSF-конвертер для PhotographId учебный класс.

    @FacesConverter(forClass=PhotographId.class)
    public class PhotographIdConverter implements Converter {
    
        @Override
        public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
            // Write code here which converts PhotographId to its unique String representation.
        }
    
        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
            // Write code here which coverts the PhotographId's unique String representation as created in above method back to the original PhotographId object.
        }
    
    }
    

Тем не менее, модель выглядит странно. Содержание фотографии является частью составного ключа..?? Это очень и очень неэффективно как для SQL, так и для Java. С тем же успехом вы можете проверить его и исправить (а затем вам нужно будет изменить <o:graphicImage> использование соответственно).

Кроме того, сообщение о том, что вы пытаетесь добавить его в блок catch для стримера, нигде не будет отображаться, поскольку запрос изображения не представляет страницу JSF. Тебе лучше просто зайти / отправить по почте.

Другие вопросы по тегам