HttpServletResponse as an argument - http

I am pretty new to servlets and I would like to ask a kind of silly question.
I have a method that has an HttpServletResponse argument and I need to call this method from my main method to run the Java program.
The thing is I do not know what should I pass as value for this argument.
Let's say I have this class that comes from CrystalReports:
private static void exportIt(ReportClientDocument clientDoc, ExportOptions exportOptions, HttpServletResponse response, boolean attachment, String mimeType, String extension)
throws ReportSDKExceptionBase, IOException {
InputStream is = null;
try {
is = new BufferedInputStream(clientDoc.getPrintOutputController().export(exportOptions));
byte[] data = new byte[1024];
response.setContentType(mimeType);
if (attachment)
{
String name = clientDoc.getReportSource().getReportTitle();
if (name == null)
{
name = "CrystalReportViewer";
}
else
{
name = name.replaceAll("\"", "");
}
response.setHeader("Content-Disposition",
"attachment; filename=\"" + name + "."+extension+"\"");
}
OutputStream os = response.getOutputStream();
while (is.read(data) > -1) {
os.write(data);
}
} finally {
if (is != null) {
is.close();
}
}
}
When I try to call the exportIt method I need to pass something in the HTTPServletResponse but I do not know what is the exact value.
Thank you for your help,

Related

Blank CSV file generated,need to write data stored inside List<List<Object>

I need to create and download the CSV file, and for this I am using OpenCSV with Spring MVC, the data need to be written is holding by my class name CsvDataDto.
public class CsvDataDto {
private String fileName;
List<String> header=new ArrayList<>();;
private String heading;
List<List<Object>> data=new ArrayList<>();
//getters and setters
}
The main data contains file header (eg: userid,fname,lastname,rollno) and actual data (eg. 1,101,john,doe,1001).
File header is hold by List<String> header
and The file data is hold by List<List<Object>> data
and here is the controller method which set all the required data
#RequestMapping(value = "/export_data")
public void downloadDataInCsv(
#RequestParam("type") String type,
#RequestParam("tID") String tableId,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (type.equals("csv")) {
CsvDataDto dataDTO = new CsvDataDto();
dataDTO.setFileName("Table_Data");
dataDTO.getHeader().add("User Id");
dataDTO.getHeader().add("First Name");
dataDTO.getHeader().add("Last Name");
dataDTO.getHeader().add("Roll No");
dataDTO.getHeader().add("Email ID");
dataDTO.getHeader().add("Gender");
List<UserInfo> list = userInfoDao.findById(tableId);
for (UserInfo infoList : list) {
List<Object> newList = new ArrayList<>();
newList.add(infoList.getUserId());
newList.add(infoList.getFirstName());
newList.add(infoList.getLastName());
newList.add(infoList.getRollNo());
newList.add(infoList.getEmail());
newList.add(infoList.getGender());
dataDTO.getData().add(newList);
}
ExportCsvUtil.downloadCsv(request, response, dataDTO);
}
Now the downloadCsv() implementation
public static void downloadCsv(HttpServletRequest request, HttpServletResponse response, CsvDataDto csvDataDto) throws IOException {
List<String[]> records = new ArrayList<>();
String csvFileName = csvDataDto.getFileName();
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=" + csvDataDto.getFileName() + ".csv");
response.setContentType("text/csv");
response.setHeader(headerKey, headerValue);
CSVWriter writer = new CSVWriter(new FileWriter(csvFileName));
String[] headerArr = new String[csvDataDto.getHeader().size()];
headerArr = csvDataDto.getHeader().toArray(headerArr);
records.add(headerArr);
for (List<Object> objList : csvDataDto.getData()) {
System.out.println("object list:" + objList);
String[] fileData = new String[objList.size()];
fileData = objList.toArray(fileData);
records.add(fileData);
}
writer.writeAll(records);
writer.close();
System.out.println(writer);
}
}
I am stuck here,as I explore tons of examples where the instructors simple pass the data in writeNext() method.
writer.writeNext(csvDataDto);
But I know that it will not work as i expected.File is successfully downloaded but blank, no data is write over it.
I want to implement the logic in such a way, so I get the CSV like below
userid, fname,lastname,rollno,gender (List<String> header)
1 , john, doe ,1001, M (List<List<Object>> data)
2 , Rose, Mary ,1002, F
3 , Jack, Jill ,1003, M
What is the best way to achieve the same by using writeNext().
#RequestMapping(value = "/export_data")
public void downloadDataInCsv(
#RequestParam("type") String type,
#RequestParam("tID") String tableId,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (type.equals("csv")) {
List<UserInfo> list = userInfoDao.findById(tableId);
ExportCsvUtil.downloadCsv(request, response, list);
}
}
private void downloadCsv(HttpServletRequest request, HttpServletResponse response, List<UserInfo> list) throws IOException {
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=Table_Data.csv");
response.setContentType("text/csv");
response.setHeader(headerKey, headerValue);
try (final CSVWriter writer = new CSVWriter(response.getWriter(), ",")) {
writer.writeNext(new String[]{"User Id", "First Name", "Last Name", "Roll No", "Email ID", "Gender"});
for (UserInfo entry: list) {
// cast/convert to String where needed
writer.writeNext(new String[]{entry.getUserId()+"", entry.getFirstName(), entry.getLastName(),entry.getRollNo(),entry.getEmail(),entry.getGender()});
}
writer.close();
}
}

Can't download file. Browser opens it instead.

I have tried a lot of contentTypes and headers I have seen here but still can't figure out what I am doing wrong. I have the following Spring Controller:
#RequestMapping(value = "/anexo/{id}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<String> getAnexoById(#PathVariable int id, HttpServletResponse response) {
Anexo a = anexoDAO.getAnexo(id);
if (a == null)
return new ResponseEntity<String>(HttpStatusMessage.NOT_FOUND, HttpStatus.NOT_FOUND);
else {
try {
File dir = new File("temp");
if (!dir.exists())
dir.mkdirs();
String filePath = dir.getAbsolutePath() + File.separator + a.getName();
File serverFile = new File(filePath);
FileInputStream fistream = new FileInputStream(serverFile);
org.apache.commons.io.IOUtils.copy(fistream, response.getOutputStream());
response.setHeader("Content-Disposition", "attachment; filename=" + a.getName());
response.setContentType("application/octet-stream");
response.setHeader("Content-Length", String.valueOf(serverFile.length()));
response.setHeader("Content-Transfer-Encoding", "binary");
response.flushBuffer();
System.out.println(response.toString());
return new ResponseEntity<String>(HttpStatus.OK);
} catch (IOException ex) {
return new ResponseEntity<String>("Exception on getting file", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
I also have tried with and without #ResponseBody.
The user will be able to upload any type of file to the server and then he will be able to download through this controller. The problem is that instead of the download window, the browser open the file in the page. How can I make it download?
Thanks in advance
This work for me:
#ResponseBody
void getOne(#PathVariable("id") long id, HttpServletResponse response) throws IOException {
MyFile file = fileRepository.findOne(id);
if(file == null) throw new ResourceNotFoundException();
response.setContentType(file.getContentType());
response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() +"\"");
response.setContentLength(file.getData().length);
FileCopyUtils.copy(file.getData(), response.getOutputStream());
}
Where MyFile is a class like this:
class MyFile {
private Long id;
private String contentType;
private String name;
private bit[] data;
...
}

Spring MVC: After exception also 200 OK response

I have below controller
#RequestMapping(value="fetchprofilepics/{profileId}/{column}/{random}",method=RequestMethod.GET)
public void fetchProfilePhoto(HttpServletResponse response, #PathVariable String profileId, #PathVariable String column, #PathVariable String random) throws IOException, ContentDeletedException
{
BufferedOutputStream bufferedOutputStream = null;
try {
//.............
bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
ByteBuffer byteBuffer = imgService.getProfilePhoto(cqlSession, column, profileId);
if(byteBuffer==null) throw new ContentDeletedException();
byte bytes[] = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes, 0, bytes.length);
bufferedOutputStream.write(bytes);
} catch (IOException ex) {ex.printStackTrace();}
finally{if(bufferedOutputStream!=null) bufferedOutputStream.close();}
throw new ContentDeletedException();
}
if byteBuffer is null it throws ContentDeletedException in tomcate log but in browser console it still show 200OK response. So in client side its showing empty image.
Why? It should not throw 200 OK status.
I found solution. I am doing this:
if(byteBuffer==null){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
else{
byte bytes[] = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes, 0, bytes.length);
bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
bufferedOutputStream.write(bytes);
}

Write Glassfish output into servlet html page

How to redirect Glassfish server output into HttpServletResponse.out? I am making servlet in NetBeans.
here is a working example, just expose this as a servlet
public class ReadLogs extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=UTF-8";
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.append("<html>\n<head>\n\n");
out.append("<script>function toBottom()" + "{"
+ "window.scrollTo(0, document.body.scrollHeight);" + "}");
out.append("\n</script>");
out.append("\n</head>\n<body onload=\"toBottom();\">\n<pre>\n");
try {
File file = new File("C:\\pathToServerLogFile");
BufferedReader in = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
while (in.ready()) {
String x = in.readLine();
sb.append(x).append("<br/>");
}
in.close();
out.append("\n</pre>\n</body>\n</html>");
out.close();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
UPDATE
If you need to print only the last portion of the file use this after line "in.close();"
//print only 1MB Oof data
if(sb.length()>1000000){
out.append(sb.substring(sb.length()-1000000, sb.length()));
}else{
out.append(sb.toString());
}
So.. to print only lines which appeared after invoking script I've made such code:
BufferedReader reader = new BufferedReader(new FileReader("/path/to/server/log/server.log"));
int lines = 0;
while (reader.readLine() != null) {
lines++;
}
reader.close();
BufferedReader reader2 = new BufferedReader(new FileReader("/path/to/server/log/server.log"));
String strLine;
int i = 0;
while (i != lines) {
reader2.readLine();
i++;
}
while ((strLine = reader2.readLine()) != null) {
out.println(stringToHTMLString(strLine));
out.println("<br>");
}
reader2.close();
When servlet starts it counts lines in server log (saves it in variable i), then after clicking on action form it read lines which indexes are higher than i and displays it on html page. I've used function stringToHTMLString which I found somewhere on stackoverflow.
Greets.

How to encode xml to Base64 and send back as servlet response?

I wrote a servlet (with .groovy extension) which should return xml in Base64 encoding
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String fileName=(String) request.getParameter("fileName")
if (fileName == null || fileName.equals(""))throw new ServletException("Invalid or non-existent file parameter in SendXml servlet.")
if (fileName.indexOf(".xml") == -1)fileName = fileName + ".xml"
System.out.println(fileName)
try {
String relativeWebPath = "/WEB-INF/classes/com/abc/csm/xml/"+fileName
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath)
String fileContents=new File(absoluteDiskPath).text
response.setContentType("text/xml")
response.addHeader("Content-Disposition", "attachment filename="+ fileName)
XmlHandler xm=new XmlHandler()
PrintWriter out = response.getWriter()
String enxml=xm.encodeBase64(fileContents)
response.setContentLength((int) enxml.length)
out.println(enxml)
out.close()
out.flush()
} catch (Exception e) { println e }
}
XmlHandler encodeBase64 method
def encodeBase64(String text) {
return new String(Base64.encodeBase64(text.getBytes()))
}
But I guess something is missing. Please help
Update
Also please comment is it proper way to access files from package?
You can replace:
String enxml=xm.encodeBase64(fileContents)
with
String enxml = fileContents.bytes.encodeBase64()
Or, better to pass an encoding to the call to getBytes:
String enxml = fileContents.getBytes( 'UTF-8' ).encodeBase64()
Also, I believe you're missing a semicolon after attachment in your header... The line should read:
response.addHeader( "Content-Disposition", "attachment; filename=$fileName" )
Edit, and encoding and decoding example:
Encode:
String encoded = "tim_yates".getBytes( 'UTF-8' ).encodeBase64()
Decode:
String original = new String( encoded.decodeBase64(), 'UTF-8' )
assert original == 'tim_yates'

Resources