9

私は人を作成するビュースコープのBeanを持っています。人は写真を持つことができます。この写真は、人物が作成されたのと同じページにアップロードされています。写真はデータベースにもディスクにも保存されません (人物がまだ作成されていないため)。人は他の場所で作成することができ、これは同じ Bean を使用するため、Bean はビュー スコープである必要があります。Bean がセッション スコープであり、ユーザーが画像をアップロードしても人物を保存しない場合、ユーザーが次に人物を作成しようとしたときに画像が表示されます。

2 つの Bean を使用してこれを解決しました。1 つのビュー スコープ Bean を使用して人物を作成し、セッション スコープ Bean を使用して写真をアップロードし、写真をストリームとして取得します。ただし、これにより、上記の問題が発生します。

どうすればこれをより良い方法で解決できますか?

アップロード Bean:

@ManagedBean(name = "uploadBean")
@SessionScoped
public class UploadBean
{
    private UploadedFile    uploadedFile;

    public UploadedFile getUploadedFile()
    {
        return uploadedFile;
    }

    public StreamedContent getUploadedFileAsStream()
    {
        if (uploadedFile != null)
        {
            return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()));
        }
        return null;
    }

    public void uploadFile(FileUploadEvent event)
    {
        uploadedFile = event.getFile();
    }
}

create-a-person Bean:

@ManagedBean(name = "personBean")
@ViewScoped
public class PersonBean
{
    private Person newPerson = new Person();

    public Person getNewPerson()
    {
        return newPerson;
    }

    private UploadedFile getUploadedPicture()
    {
        FacesContext context = FacesContext.getCurrentInstance();
        ELContext elContext = context.getELContext();
        UploadBean uploadBean = (UploadBean) elContext.getELResolver().getValue(elContext, null, "uploadBean");
        return uploadBean.getUploadedFile();
    }

    public void createPerson()
    {
        UploadedFile uploadedPicture = getUploadedPicture();
        // Create person with picture;
    }
}

関連する JSF ページ部分:

<h:form enctype="multipart/form-data">
    <p:outputPanel layout="block" id="personPicture">
        <p:graphicImage height="150"
            value="#{uploadBean.uploadedFileAsStream}"
            rendered="#{uploadBean.uploadedFileAsStream != null}" />
    </p:outputPanel>
        <p:fileUpload auto="true" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
            fileUploadListener="#{uploadBean.uploadedFile}"
            update="personPicture" />
    <p:commandButton value="Save" actionListener="#{personBean.createPerson()}"/>
</h:form>
4

3 に答える 3

4

私は別のアプローチに行きました。最初はアップロードされた画像を表示することにしましたPersonが、まだ作成されていない場合は、すべてクライアント側に保持することをお勧めします。この質問を見つけ、選択した回答に基づいて以下を作成しました。

ブラウザーが IE で、互換性のためにバージョンが 9 未満の場合、頭にhtml5shivを含めます。

<h:outputText value="&lt;!--[if lt IE 9]&gt;" escape="false" />
<h:outputScript library="js" name="html5shiv.js" />
<h:outputText value="&lt;![endif]--&gt;" escape="false" />

画像を表示/アップロードするには、次の要素があります。

<p:fileUpload binding="#{upload}" mode="simple"
    allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
    value="#{personBean.uploadedPicture}"/>
<p:graphicImage value="#" height="150" binding="#{image}" />

そしていくつかの JavaScript/jQuery マジック:

function readPicture(input, output)
{
    if (input.files && input.files[0])
    {
        var reader = new FileReader();
        reader.onload = function(e)
        {
            output.attr('src', e.target.result);
        };
        reader.readAsDataURL(input.files[0]);
    }
}

$("[id='#{upload.clientId}']").change(
    function()
    {
        readPicture(this, $("[id='#{image.clientId}']"));
    });

uploadedPictureプロパティは単純なプロパティになりました。

@ManagedBean(name = "personBean")
@ViewScoped
public class PersonBean
{
    private UploadedFile uploadedPicture;

    public UploadedFile getUploadedPicture()
    {
        return uploadedPicture;
    }

    public void setUploadedPicture(UploadedFile uploadedPicture)
    {
        this.uploadedPicture = uploadedPicture;
    }
}
于 2012-09-05T21:43:27.530 に答える
0

<img>アップロードされた画像をbase64にエンコードし、htmlタグを介して通常どおり表示するだけで、なんとかそれを実現できました。

これが私のマネージドBeanです:

@ManagedBean
@ViewScoped
public class ImageMB {

private String base64Image;

public void onUploadImage(FileUploadEvent event) {
    String fileName = event.getFile().getFileName();
    //Get file extension.
    String extension = "png";
    int i = fileName.lastIndexOf('.');
    if (i > 0) {
        extension = fileName.substring(i + 1).toLowerCase();
    }

    String encodedImage = java.util.Base64.getEncoder().encodeToString(event.getFile().getContents());
    this.base64Image = String.format("data:image/%s;base64, %s", 
         extension, encodedImage));
}

そして、ここにJSFの部分があります:

<p:fileUpload id="imageFileUploader"
              fileUploadListener="#{imageMB.onUploadImage}"
              mode="advanced"    
              multiple="false"
              fileLimit="1"
              allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
              update="@form"/>

<div>
    <img src="#{toolAddEditMB.base64Image}" 
         style="#{toolAddEditMB.base64Image eq null ? 'display: none' : ''}"/>
</div>
于 2019-03-13T15:29:32.917 に答える