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

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();
}
}

Related

Resttemplate Returns 500 Response Message

I am trying to make a post request which is supposed to return a json, but for some reason it returns 500 something went wrong.
'''
public void templatRequestPayment(String token, String url, String key, String body)
throws RestClientException, URISyntaxException, IOException {
URI uri = new URI(url);
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", token);
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.set("key", key);
HttpEntity<String> entity = new HttpEntity<String>(body, headers);
RestTemplate template = new RestTemplate(getConverter());
try {
ResponseEntity<JsonNode> res = template.exchange(uri, HttpMethod.POST, entity,
JsonNode.class);
String tok = res.getBody().toString();
System.out.println(tok);
} catch (HttpStatusCodeException e) {
ResponseEntity<String> st =
ResponseEntity.status(e.getStatusCode()).headers(e.getResponseHeaders())
.body(e.getResponseBodyAsString());
System.out.println(st.getHeaders() + "-- /n" + st.getBody());
}
}
protected List<HttpMessageConverter< ?>> getConverter() {
List<HttpMessageConverter< ?>> converters = Lists.newArrayList();
converters.add(new MappingJackson2HttpMessageConverter());
return converters;
}
'''

HttpServletResponse as an argument

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,

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;
...
}

How to get data from servlet by extjs

i create an jsonarray and sent from servlet, and sent to the front side,
the front side should get the message and currentTime, and show them in the website. How should i do that in EXTjs:
Here is the code in the servelet:
public void loadHistory(HttpServletRequest request, HttpServletResponse response) throws IOException{
JsonObject json = new JsonObject();
JsonArray dataArray = new JsonArray();
String groupName = request.getParameter("groupName");
String chatRoomName = getChatRoom(groupName);
Database db = new Database(chatRoomName);
CouchDbClient dbClient = db.getDbClient();
PrintWriter out = response.getWriter();
int i=0;
while (dbClient.contains(String.valueOf(i++))){
JsonObject objHistory = dbClient.find(JsonObject.class, String.valueOf(i++));
String preMessage = objHistory.get("message").getAsString();
String preTime = objHistory.get("currentTime").getAsString();
json.addProperty("message", preMessage);
json.addProperty("currentTime", preTime);
dataArray.add(json);
}
if (dataArray!=null){
response.setContentType("application/json");
out.print(dataArray);
out.close();
}
}
modify the below code in the if conditon before sending the response.
if (dataArray!=null){
response.setContentType("application/json");
JSONObject resultJsonMain=new JSONObject();
resultJsonMain.put("resultJsonMain",dataArray);
out.println(resultJsonMain);
out.close();
}

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.

Resources