How do I change this try-finally to try-with-resources? - java

This is the code.
Most of the examples do not let me to use response variable which I got with the function's parameter.
Is there anyone who can help me with this question?
Or is it better to use try-finally than try-with-resources in this case?
public void func(HttpServletResponse response) throws IOException {
OutputStream out = null;
InputStream in = null;
try {
out = response.getOutputStream();
ResponseEntity<Resource> url = getUrl();
Resource body = url.getBody();
in = body.getInputStream();
FileCopyUtils.copy(in, out);
} finally {
if (out != null) {
try {
out.close();
}catch (IOException e) {
}
}
if (in != null) {
try {
in.close();
}catch (IOException e) {
}
}
}
}

You can do it this way using try-with-resources construct
public void func(HttpServletResponse response) throws IOException {
try (OutputStream out = response.getOutputStream) {
out = response.getOutputStream();
ResponseEntity<Resource> url = getUrl();
Resource body = url.getBody();
try(InputStream in = body.getInputStream()) {
FileCopyUtils.copy(in, out);
}
}
}

Related

How to solve this Close this "FileOutputStream"

How to solve this?
I am getting the below error : Close this "FileOutputStream". but i have closes it already in finally block
public void initHistoryForOldFile(File oldFile, String filePath) throws PIDException {
InputStream inStream = null;
OutputStream outStream = null;
try {
File historyFile = new File(StringUtil.append(filePath, File.separator, "history"));
FileUtils.ensureDirectory(historyFile);
File oldHistoryFile = new File(StringUtil.append(filePath, File.separator, "history", File.separator, oldFile.getName()));
oldHistoryFile.createNewFile();
if (oldFile.exists()) {
inStream = new FileInputStream(oldFile);
outStream = new FileOutputStream(oldHistoryFile);
byte[] buffer = new byte[PIDConstants.IMAGE_FILE_SIZE_LIMIT];
int length;
// copy the file content in bytes
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
// delete the original file
oldFile.delete();
}
} catch (IOException e) {
LOGGER.error("Exception occured in historyUpdateForOldFIle", e);
} finally {
if (null != inStream) {
try {
inStream.close();
} catch (IOException e) {
LOGGER.error("Exception occured whole closing inStream", e);
}
}
if (null != outStream) {
try {
outStream.close();
} catch (IOException e) {
LOGGER.error("Exception occured whole closing outStream", e);
}
}
}
}
If using java 7
You can use Try with resources
try(InputStream inStream = new FileInputStream(oldFile)){}
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement.
try(InputStream instream = new fileinputstream(oldFile)){};

Java- How can you close `FileInputStream` in finally block if the same method returns that `FileInputStream`

Sonar is showing a bug for the below code which is of blocker type. It's complaining that I have not closed FileInputStream but how can I do that? FileInputStream is the return type of method and if I close here then it will be of no use from where it's calling. Please let me know- how can I close FileInputStream in finally block if the same method returns that FileInputStream?
Here is the code:
#Override
public InputStream getInputStream() throws MissingObjectException {
try {
InputStream is;
if (smbFile != null) {
is = new BufferedInputStream(new SmbFileInputStream(smbFile), 60000);
}
else {
is = new BufferedInputStream(new FileInputStream(getFilePath()));
}
return is;
}
catch (Exception e) {
throw new MissingObjectException();
}
}
It is not necessary to close the input in the same function. The problem may be that you should not declare InputStream is in try{} block as well as putting the return statement.
Put is declaration before try block
InputStream is= null;
try {
if (smbFile != null) {
is = new BufferedInputStream(new SmbFileInputStream(smbFile), 60000); } else {
is = new BufferedInputStream(new FileInputStream(getFilePath()));
}
return is;
}
catch (Exception e) {
throw new MissingObjectException();
}finally{
if(is !=null){
is.close();
}
}

com.lowagie.text.html: HTMLWriter added image is empty

I am writing in java, but want to create a dynamic HTML-page for the users. I am using Lowagie to create the document with HTML. I do manage to present the html, but my picture is empty. It just contain the picture-border.
Can anyone help me with this? Or tell me another way of creating HTML-pages (preferable by using ByteArrauOutputstream or other outpustreams to display the content).
The code is as follows:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String orderId = request.getParameter("id1");
String telephone = request.getParameter("id2");
response.setHeader("Expires", EXPIRES);
response.setContentType(CONTENT_TYPE);
ServletOutputStream out = null;
ByteArrayOutputStream baos = null;
try {
baos = getHtmlTicket(orderId, telephone);
response.setContentLength(baos.size());
out = response.getOutputStream();
baos.writeTo(out);
}
catch (Exception e) {
log.error(e.getMessage(), e);
}
finally {
if (out != null) {
try {
out.flush();
}
catch (Exception e) {
log.debug(e.getMessage(), e);
}
}
if (baos != null) {
try {
baos.flush();
}
catch (Exception e) {
log.debug(e.getMessage(), e);
}
}
if (out != null) {
try {
out.close();
}
catch (Exception e) {
log.warn(e.getMessage(), e);
}
}
if (baos != null) {
try {
baos.close();
}
catch (Exception e) {
log.warn(e.getMessage(), e);
}
}
}
public ByteArrayOutputStream getHtmlTicket(String orderId, String telephoneTest) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Document document = new Document();
Order order = orderService.getOrder(Integer.parseInt(orderId));
String fileType = "png";
String filePath = "html/picture.png";
File myFile = new File(filePath);
try {
HtmlWriter.getInstance(document, baos);
document.open();
document.add(new Paragraph("Hello World"));
Image fileImage = Image.getInstance(filePath);
document.add(fileImage);
document.add(new Paragraph("osv"));
}
catch (DocumentException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
document.close();
return baos;
}

Why do I need to catch a close() exception in BufferedReader but not in PrintWriter?

I have a simple file read and write function.
private void WriteToFile(String filename, String val) {
PrintWriter outStream = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filename);
outStream = new PrintWriter(new OutputStreamWriter(fos));
outStream.print(val);
outStream.close();
} catch (Exception e) {
if (outStream != null) {
outStream.close();
}
}
}
private String ReadFile(String filename) {
String output = "";
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(filename);
br = new BufferedReader(fr);
output = br.readLine();
br.close();
} catch (Exception e) {
if (br != null) {
br.close();
}
}
return output;
}
When building I get:
unreported exception java.io.IOException; must be caught or declared to be thrown
br.close();
^
Why do I need to catch br.close but it doesn't complain about WriteToFile's close()?
Taken from the source code of java.io.PrintWriter:
public void close() {
try {
synchronized (lock) {
if (out == null)
return;
out.close();
out = null;
}
}
catch (IOException x) {
trouble = true;
}
}
The IOException was eaten up within the close() method in PrintWriter
From source code of java.io.BufferedReader:
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
in.close();
in = null;
cb = null;
}
}
BufferedReader throws the IOException.
That should answer your question.
Why do I need to catch br.close but it doesn't complain about WriteToFile's close()?
You can check the Java Docs for this. The close() method for BufferedReader :
public void close()
throws IOException
And the close() method for PrintWriter :
public void close()
That answer's your question as to why JVM doesn't complain. Because it is clear from the method signatures;
PrinterWriter.close() doesn't throw any Exception.
If you call fos.close(), it will ask you to catch/throw the exception.
In the PrintWriter.java. The exception is caught and handled. So you needn't catch it while using.
Java Source:
public void close() {
try {
synchronized (lock) {
if (out == null)
return;
out.close();
out = null;
}
}
catch (IOException x) {
trouble = true;
}
}
But in BufferedReader the exception is thrown. So you have to catch it when using.
Java Source:
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
in.close();
in = null;
cb = null;
}
}

IllegalStateException on redirect

I have a PhaseListener which listens on phaseId RENDER_RESPONSE. This faceListener calls this method:
public void doLogin(ServletRequest request) throws IOException {
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest req = (HttpServletRequest) request;
String code = req.getParameter("code");
if (StringUtil.isNotBlankString(code)) {
String authURL = Facebook.getAuthURL(code);
URL url = new URL(authURL);
try {
....
if (accessToken != null && expires != null) {
boolean isLoginOk = service.authFacebookLogin(accessToken);
if (isLoginOk) {
fc.getApplication().getNavigationHandler().handleNavigation(fc, "/welcome.xhtml", "logged-in");
}
} else {
throw new RuntimeException("Access token and expires not found");
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (FacebookException e) {
Logger.getLogger(FBOauth.class.getName()).log(Level.SEVERE, "Facebook error", e);
}
}
}
private String readURL(URL url) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();
int r;
while ((r = is.read()) != -1) {
baos.write(r);
}
return new String(baos.toByteArray());
}
When it redirects I get the following exception which I cant really find any solution to. From what I understand it is thrown because response is already comitted but why is it already comitted?
java.lang.IllegalStateException at
org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:522)
at com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:572)
at com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:182)
at wmc.web.facebook.FBOauth.doLogin(FBOauth.java:57)
at wmc.web.listeners.FacebookSignInListener.afterPhase(FacebookSignInListener.java:56)
at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
By the way I really appreciate all the help I get in here :)
Your phaselistener is apparently hooking on afterPhase of RENDER_RESPONSE. It's too late to change the response then. The response is already been sent to the client. Rather hook on beforePhase() of the `RENDER_RESPONSE.
My guess would be that before the sendRedirect() is executed some part of your code has already streamed text to the servlet repsonse, maybe some generic information that is send to all responses?

Categories

Resources