How to read a href parameter in servlet? - java

on address bar : http://localhost:8080/tryupload/downloadservlet?bookid=15bk
bookid=15bk (15bk was i got from my bookId on database, by getString on servlet)
then , below is my display on servlet (not jsp)
out.println("<TD>Download</TD>");
then it goes to
downloadservlet.java // but it didnt worked. Blank page.
How read the "boookid " from this link http://localhost:8080/tryupload/downloadservlet?bookid=15bk to my servlet? and be execute on my downloadservlet.java?
downloadservlet.java
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String bookId = request.getParameter("bookId");
Connection conn = null; // connection to the database
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
// queries the database
String sql = "SELECT * FROM books WHERE bookId = ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, bookId);
ResultSet result = statement.executeQuery();
if (result.next()) {
// gets file name and file blob data
String fileName = result.getString("BookContent");
Blob blob = result.getBlob("BookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("fileLength = " + fileLength);
ServletContext context = getServletContext();
// sets MIME type for the file download
String mimeType = context.getMimeType(fileName);
if (mimeType == null) {
mimeType = "application/octet-stream";
}
// set content properties and header attributes for the response
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", fileName);
response.setHeader(headerKey, headerValue);
// writes the file to the client
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
} else {
// no file found
response.getWriter().print("File not found for the id: " + bookId);
}
} catch (SQLException ex) {
ex.printStackTrace();
response.getWriter().print("SQL Error: " + ex.getMessage());
} catch (IOException ex) {
ex.printStackTrace();
response.getWriter().print("IO Error: " + ex.getMessage());
} finally {
if (conn != null) {
// closes the database connection
try {
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
}

you read the parameter correctly with
request.getParameter("bookid")
However you cannot apply directly Integer.parseInt as you read 15bk and which is not an integer, if you need 15 out of 15 bk you need an additional step of parsing.
Following your last edit, its the same issue - you cannot do
statement.setInt(1, bookid);
bookid will not be an int. you need to parse, not sure but for example if you want to eliminate the last 2 characters you could do
bookIntId = bookId.substrings(0, bookId.length - 2)

String bookId = request.getParameter("bookid");
If your parameter value is 15bk then your line of code:
int bookid = Integer.parseInt(request.getParameter("bookid"));
Will throw NumberFormatException as bk cannot be converted into an integer value.

Related

Send a String from Android to a Spring server

I am trying to send an String from my android app to the server. The String contains: username, password and a image encoded in base 64. Between them is a space(" "). I am using heroku to store the server and I use a postgreSQL database. I have a table named users with the columns : userid,password, encoded image, all of them in format text.
When I create a new user I give the userid and the password, the column encodedimage is empty. I want to make an update to the table when I want to upload the image to the server and edit the encodedimage column.
Here is how I send the String from android:
request=Utils.name+" "+Utils.password;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
request = request+ " " + Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
try {
URL url = new URL(params[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(15000);
urlConnection.setConnectTimeout(15000);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
OutputStream outputStream = urlConnection.getOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
bufferedWriter.write(request);
bufferedWriter.flush();
bufferedWriter.close();
outputStreamWriter.close();
outputStream.close();
int response=urlConnection.getResponseCode();
urlConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
If I update my table from cmd it works but from code it doesn't.
Here is my controller:
#Controller
public class UploadController implements Constant {
#RequestMapping(value = "/upload-image", method = RequestMethod.POST)
public void handleUploadImageRequest(#RequestBody String request) {
String[] details = request.split(" ");
String name = details[0];
String password = details[1];
byte[] decodedImage = Base64.getDecoder().decode(details[2]);
if (decodedImage.length > 0) {
try {
Image image = ImageIO.read(new ByteArrayInputStream(decodedImage));
Connection connection = null;
Statement statement = null;
String updateUSER = "UPDATE " + TABLE_USERS + " SET " + COLUMN_ENCODEDIMAGE + "='" + details[2]
+ "' WHERE " + COLUMN_USERID + "='" + name + "' AND '" + COLUMN_PASSWORD + "='" + password + "';";
try {
connection = DatabaseUtils.getConnection();
statement = connection.createStatement();
statement.executeUpdate(updateUSER);
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
In heroku logs I found:
org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public void com.rares.controllers.UploadController.handleUploadImageRequest(java.lang.String)
Is the android code ok? Where is the problem or how should I do it. Please don't point me to deprecated methods.
I
Wrong posting. Your request should more look like:
request = "username=" + userName
+ "&password=" + passWord
+ "&image=" + base64String.
And then the values should be url encoded yet.

Prevent downloaded files from replacing or overwriting each other

How to download all file types in MySQL database using Java app and prevent one file from replacing the other?
How can I include all file types in my filepath=("D:\\sch work\\skirt\\filename.pdf"); so that I am able to download pdf, docx, jpeg etc, from a MySQL database using Java mouse click event on a JTable?
I have two problems.
I can only open a PDF files although I want to open docs, JPEG and img files.
Every time I download another file from a different row it replaces the existing one. I would like to keep all of them
Below please find my code for mouse click event and please suggest what I should add for it to work as I need it.
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
String filePath =("D:\\sch work\\skirt\\filename.pdf");
int BUFFER_SIZE = 4096;
try {
int cert_code= jTable1.getSelectedRow();
String tableClick=(jTable1.getModel().getValueAt(cert_code,3).toString());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee_certificate","root","");
String sql= "SELECT cert FROM certificate WHERE cert_code =?" ;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, tableClick);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
Blob blob = rs.getBlob("cert");
InputStream inputStream = blob.getBinaryStream();
OutputStream outputStream = new FileOutputStream(filePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//JOptionPane.showMessageDialog(null,"file saved")
} }
catch (Exception e)
{JOptionPane.showMessageDialog(null,e);}
}
If you want something other than PDF, you should store what's in that cert blob, so you can send out the appropriate filename/type:
You get PDF because that's the exact+only file type you write out to:
String filePath =("D:\\sch work\\skirt\\filename.pdf");
^^^
Perhaps something more like (in pseudo-code):
select cert,filename,filetype from ...
filepath = 'd:\sch work\skirt' + filename
header('Content-type: ' + filetype);
here is my answer.God bless Marc B abundantly.
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
int BUFFER_SIZE = 4096;
try {
int cert_code= jTable1.getSelectedRow();
String tableClick=(jTable1.getModel().getValueAt(cert_code,3).toString());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee_certificate","root","");
String sql= "SELECT cert, cert_name FROM certificate WHERE cert_code =?" ;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, tableClick);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
String filename = rs.getString("cert_name");
Blob blob = rs.getBlob("cert");
InputStream inputStream = blob.getBinaryStream();
String filePath ="D:\\sch work\\skirt\\"+filename;
OutputStream outputStream = new FileOutputStream(filePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//JOptionPane.showMessageDialog(null,"file saved")
} }
catch (Exception e)
{JOptionPane.showMessageDialog(null,e);}
}

fileLength = 0 When trying to Download PDF File from Database

fileLength = 0
File Reading Success
getting file Length as null when trying to download pdf file from DATABASE.
Actually have to get Some PDF File which has Some content that was stored in local database
Would You Please Help Me on this Particular ISSue , What should do now to resolve this problem and file was uploaded through Client Side Program Only
public class FileDownload extends HttpServlet {
private static final int BUFFER_SIZE = 40960;
protected void doGet(--){
String bookId = request.getParameter("bookId");
Connection conn=null;
try {
Class.forName("--");
Connection con=DriverManager.getConnection("--");
String sql="SELECT * from book where bookId=?";
PreparedStatement statement = con.prepareStatement(sql);
statement.setString(1, bookId);
ResultSet result = statement.executeQuery();
if(result.next()) {
String bookTitle = result.getString("bookTitle");
Blob blob = result.getBlob("bookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("fileLength = " +fileLength);
ServletContext context = getServletContext();
String mimeType = context.getMimeType(bookTitle);
if (mimeType == null) {
mimeType = "application/pdf";
}
System.out.println("File Reading Success");
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; fileName=\"%s\"", bookTitle +".pdf");
response.setHeader(headerKey, headerValue);
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1){
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
}
InputStream.available() does not return the file length, but rather the number of bytes which can be read from the stream without blocking. Most likely the database does not send any bytes of the Blob until you explicitly request the content, and so 0 is returned.
Therefore use
int fileLength = blob.length();
which gives you the exact length of the file.

How to download .msi file in Java

I want to download .msi file using Java. I have tried to download file using following code
PrintWriter out = null;
FileInputStream fileToDownload = null;
BufferedReader bufferedReader = null;
try {
out = response.getWriter();
fileToDownload = new FileInputStream(DOWNLOAD_DIRECTORY + FILE_NAME);
bufferedReader = new BufferedReader(new InputStreamReader(fileToDownload));
//response.setContentType("application/text");
//response.setContentType("application/x-msi");
//response.setContentType("application/msi");
//response.setContentType("octet-stream");
response.setContentType("application/octet-stream");
//response.setContentType("application/x-7z-compressed");
//response.setContentType("application/zip");
response.setHeader("Content-disposition","attachment; filename=" +FILE_NAME );
response.setContentLength(fileToDownload.available());
System.out.println("\n now file download is starting");
String NextLine = "";
while((NextLine = bufferedReader.readLine()) != null){
out.println(NextLine);
}
out.flush();
} catch (IOException e) {
out.write("<center><h2>The Installer is not Available on Server</h2></center>");
System.out.println("\n Got Exception while getting the input Stream from the file==>"+e);
log.error("Error::", e);
}
finally{
if(null != bufferedReader){
try {
bufferedReader.close();
} catch (IOException e) {
System.out.println("\n Error in closing buffer Reader==>"+e);
log.error("Error::", e);
}
}// End of if
if(null != fileToDownload){
try {
fileToDownload.close();
} catch (IOException e) {
System.out.println("\n Error in closing input stream==>"+e);
log.error("Error::", e);
}
}// End of if
}// End of finally
You Can't read binary(msi) file with readline() in this case.Your Code is totally wrong and will not work.
Here is a simple function which lets you do what you want.
private void doDownload( HttpServletRequest req, HttpServletResponse resp,String filename, String original_filename )throws IOException
{
File f = new File(filename);
int length = 0;
ServletOutputStream op = resp.getOutputStream();
ServletContext context = getServletConfig().getServletContext();
String mimetype = context.getMimeType( filename );
resp.setContentType( (mimetype != null) ? mimetype : "application/octet-stream" );
resp.setContentLength( (int)f.length() );
resp.setHeader( "Content-Disposition", "attachment; filename=\"" + original_filename + "\"" );
byte[] bbuf = new byte[BUFSIZE];
DataInputStream in = new DataInputStream(new FileInputStream(f));
while ((in != null) && ((length = in.read(bbuf)) != -1)){
op.write(bbuf,0,length);
}
in.close();
op.flush();
op.close();
}
Create doDownload() function in your servlet and pass requierd parameters to that function from doGet,doPost or whatever valid place you like.
Parameters:
#param req The request
#param resp The response
#param filename The name of the file you want to download.
#param original_filename The name the browser should receive.

Download a file through an HTTP Get in java

I've written a download Servlet to return a file based on a messageID parameter. Below is the doGet method.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// This messageID would be used to get the correct file eventually
long messageID = Long.parseLong(request.getParameter("messageID"));
String fileName = "C:\\Users\\Soto\\Desktop\\new_audio1.amr";
File returnFile = new File(fileName);
ServletOutputStream out = response.getOutputStream();
ServletContext context = getServletConfig().getServletContext();
String mimetype = context.getMimeType("C:\\Users\\Soto\\Desktop\\new_audio1.amr");
response.setContentType((mimetype != null) ? mimetype : "application/octet-stream");
response.setContentLength((int)returnFile.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + "new_audio.amr" + "\"");
FileInputStream in = new FileInputStream(returnFile);
byte[] buffer = new byte[4096];
int length;
while((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
}
I then wrote some code to retrieve the file.
String url = "http://localhost:8080/AudioFileUpload/DownloadServlet";
String charset = "UTF-8";
// The id of the audio message requested
String messageID = "1";
//URLConnection connection = null;
try {
String query = String.format("messageID=%s", URLEncoder.encode(messageID, charset));
//URLConnection connection;
//URL u = new URL(url + "?" + query);
//connection = u.openConnection();
//InputStream in = connection.getInputStream();
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpGet httpGet = new HttpGet(url + "?" + query);
HttpResponse response = httpClient.execute(httpGet);
System.out.println(response.getStatusLine());
InputStream in = response.getEntity().getContent();
FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\Soto\\Desktop\\new_audio2.amr"));
byte[] buffer = new byte[4096];
int length;
while((length = in.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
//connection = new URL(url + "?" + query).openConnection();
//connection.setRequestProperty("Accept-Charset", charset);
//InputStream response = connection.getInputStream();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Now this code works fine. I can download the audio file and it works correctly. What I want to know is how to, if possible, get the name of the file as it is downloaded instead of giving it my own name. Also, is it possible to get the file without having to read from the stream (maybe some library that does it for you)? I kind of want to hide the dirty stuff.
Thanks
For setting the download file name do the following on response object in Servlet code
response.setHeader("Content-disposition",
"attachment; filename=" +
"new_audio1.amr" );
EDIT:
I see you are already doing it. Just try removing the slashes you have added.
With attachment, the file will be served with the provided name properly. When inline, browsers seem to ignore filename, and usually give the servletname part of the URL as default name when saving the inline contents.
You could try mapping that URL to an appropriate filename, if that is suitable.
Here's a SO related question: Securly download file inside browser with correct filename
You may also find this link useful: Filename attribute for Inline Content-Disposition Meaningless?
I think you cannot download file without streaming. For I/O you must use stream.

Categories

Resources