である私は、JSF 2.3を使用してファイルのアップロードを実装しようとしています:列「ファイルは」型のOIDですが、式はbyte型
@Inject
@Push
private PushContext uploadProgress;
private static final Logger logger = Logger.getLogger(NewProcedure.class.getName());
private Part file;
public Part getFile()
{
return file;
}
public void setFile(Part file)
{
this.file = file;
}
public void upload() throws SQLException
{
if (file != null)
{
try (InputStream inputStream = file.getInputStream();
//FileOutputStream outputStream = new FileOutputStream(path)
)
{
long lastTimestamp = System.currentTimeMillis();
int pushInterval = 1000;
long totalRead = 0;
long size = file.getSize();
int bytesRead = 0;
final byte[] chunck = new byte[1024];
while ((bytesRead = inputStream.read(chunck)) != -1)
{
// outputStream.write(chunck, 0, bytesRead);
totalRead += bytesRead;
if (System.currentTimeMillis() > lastTimestamp + pushInterval)
{
lastTimestamp = System.currentTimeMillis();
uploadProgress.send(100.0 * totalRead/size); // Make sure this isn't sent more often than once per second.
}
}
Connection conn = ds.getConnection();
// insert into database file
PreparedStatement ps = null;
boolean committed = false;
try
{
conn.setAutoCommit(false);
ps = conn.prepareStatement("INSERT INTO PROCEDURE_FILES (ID, PROCEDURE_ID, FILE_NAME, FILE) "
+ " VALUES (?, ?, ?, ?)");
ps.setInt(1, obj.number);
ps.setInt(2, obj.number);
ps.setString(3, "tests");
ps.setBinaryStream(4, inputStream);
ps.executeUpdate();
ps.close();
conn.commit();
committed = true;
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
if (!committed)
{
conn.rollback();
}
if (ps != null)
{
ps.close();
}
conn.close();
}
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Upload successfully ended!"));
}
catch (IOException e)
{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Upload failed!"));
}
}
}
私は、データベースに直接ファイルを挿入したいと思いますが、私はエラーを取得します:
org.postgresql.util.PSQLException: ERROR: column "file" is of type oid but expression is of type bytea
Hint: You will need to rewrite or cast the expression.
ファイルをデータベースに挿入する適切な方法は何ですか? おそらく私はファイルを格納するために他のJava Objectを使用する必要がありますか?
public static byte[] getBytesFromInputStream(InputStream is) throws IOException
{
try (ByteArrayOutputStream os = new ByteArrayOutputStream();)
{
byte[] buffer = new byte[0xFFFF];
for (int len; (len = is.read(buffer)) != -1;)
os.write(buffer, 0, len);
os.flush();
return os.toByteArray();
}
}
public void upload() throws SQLException
{
if (file != null)
{
try
{
InputStream inputStream = file.getInputStream();
byte[] bytesFromInputStream = getBytesFromInputStream(inputStream);
ByteArrayInputStream input = new ByteArrayInputStream(bytesFromInputStream);
long lastTimestamp = System.currentTimeMillis();
int pushInterval = 1000;
long totalRead = 0;
long size = file.getSize();
int bytesRead = 0;
final byte[] chunck = new byte[1024];
while ((bytesRead = inputStream.read(chunck)) != -1)
{
// outputStream.write(chunck, 0, bytesRead);
totalRead += bytesRead;
if (System.currentTimeMillis() > lastTimestamp + pushInterval)
{
lastTimestamp = System.currentTimeMillis();
uploadProgress.send(100.0 * totalRead/size); // Make sure this isn't sent more often than once per second.
}
}
Connection conn = ds.getConnection();
// insert into database file
PreparedStatement ps = null;
boolean committed = false;
try
{
conn.setAutoCommit(false);
ps = conn.prepareStatement("INSERT INTO PROCEDURE_FILES (ID, PROCEDURE_ID, FILE_NAME, FILE) "
+ " VALUES (?, ?, ?, ?)");
ps.setInt(1, obj.number);
ps.setInt(2, obj.number);
ps.setString(3, file.getSubmittedFileName());
ps.setBinaryStream(4, input, input.available());
ps.executeUpdate();
ps.close();
conn.commit();
committed = true;
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{}
}
catch (IOException e)
{}
}
}
'ps.setBinaryStream(4値、INPUTSTREAM、file.length());' 引用: 'にsetBinaryStreamに長さパラメータが正確でなければなりません。ストリームの長さが不明であることを示す方法はありません。このような状況にある場合は、ストリームを一時的な記憶域に読み込んで長さを判断する必要があります。正しい長さで、一時的なストレージからドライバにデータを送信することができます。 '問題は' file'は実際には 'Part'(JavaMail?)です。この場合、' Content-Length'ヘッダを問い合わせる必要があります。 – Stavr00
@ Stavr00どのように長さを設定できますか?コードのどの部分から長さのサイズを取得できますか? –
-1を返す場合は、 'getSize()'から取得するか、ストリーム全体を 'ByteArayInputStream'に読み込む必要があります。 – Stavr00