I have a question regarding an REST-Interface Iam currently building. Iam normally a frontend specialist, due to no resources available, now handling backend stuff. So please patient with me :-).
Here is the Class Iam speaking of:
/**
*
* @author User
*/
@Path("/excel")
public class Excel {
private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
private static final String SERVER_UPLOAD_LOCATION_FOLDER = "C://tmp/";
@POST
@Path("/export")
//@Consumes(MediaType.APPLICATION_JSON)
@Consumes({"application/xml","application/json"})
public Response writeFile(FileContent fileContent){
//Check if anything is null, if so return a server error code 500
String startDateStr = new Date().toString();
try {
JsonParser parser = new JsonParser();
JsonObject element = (JsonObject) parser.parse(fileContent.getContent());
String fileName = startDateStr + Integer.toString(new Random().nextInt(100)) + ".xls";
FileInformation fi = new FileInformation(
fileName,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
File file = new File(fileName);
WritableWorkbook workbook = Workbook.createWorkbook(file);
WritableSheet sheet = workbook.createSheet(fileName, 0);
int i = 0;
while(element.get(Integer.toString(i)) != null && !element.get(Integer.toString(i)).getAsJsonArray().isJsonNull()) {
JsonArray line = element.get(Integer.toString(i)).getAsJsonArray();
System.out.println(i);
for(int n = 0; n < line.size(); n++)
{
System.out.println(line.get(n).toString());
Label label = new Label(n,i, line.get(n).toString());
sheet.addCell(label);
}
i++;
}
workbook.write();
workbook.close();
Runnable r = new DeleteThread(file);
new Thread(r).start();
return Response.status(201).entity(fi).header("Access-Control-Allow-Origin", "*").build();
} catch (NullPointerException | IOException | WriteException e ) {
System.out.println(e);
return Response.status(500).build();
}
}
@GET
@Path("/export")
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public Response serveFile(@QueryParam("fileName") String fileName){
File file = new File(fileName);
Response.ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition",
"attachment; filename=" + fileName);
return response.build();
}
@PUT
@Path("/import")
@Produces
public Response putFile() {
/*@FormDataParam("file") FormDataContentDisposition contentDispositionHeader) {
String filePath = SERVER_UPLOAD_LOCATION_FOLDER + contentDispositionHeader.getFileName();
FileHelper.saveFile(fileInputStream, filePath);*/
return Response.status(200).entity("Hallo Friend").build();
}
}
Here is my POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.range_plan_viz.rest</groupId>
<artifactId>jerseyrangeplan</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>jerseyrangeplan Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>rangePlanVizRest</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<server>TomcatServer</server>
<path>/restRangePlan</path>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
</project>
Here is the mapper Class for the request payload:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.range_plan_viz.wrapper;
/**
*
* @author User
*/
public class FileContent {
private String content;
public FileContent(String content){
setContent(content);
}
/**
* @return the content
*/
public String getContent() {
return content;
}
/**
* @param content the content to set
*/
public void setContent(String content) {
this.content = content;
}
}
Here is the mapper for the response payload:
package org.range_plan_viz.wrapper;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Created by User on 12.02.2015.
*/
@XmlRootElement
public final class FileInformation {
private String fileName;
private String contentType;
/**
* Default constructor
* @param content The content of the excel file published by the UI
* @param fileName The name of the file that should be generated published by the UI
* @param contentType The contenType of the file
*/
public FileInformation(
String fileName,
String contentType
){
setFileName(fileName);
setContentType(contentType);
}
/**
* Getter of the fileName
* @return {String} The fileName of the file that should be generated
*/
public String getFileName() {
return fileName;
}
/**
* The setter of the fileName
* @param {String} fileName The fileName of the file that should be
* generated
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* The getter of the content type
* @return {String} The contentType of the file that should be generated
*/
public String getContentType() {
return contentType;
}
/**
* The setter of the content type
* @param {String} contentType The contentType of the app that should be
* generated
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
@Override
public String toString() {
return "FileInformation [fileName=" + getFileName() + ", contenType=" + getContentType() + "]";
}
}
And here is the JavaScript to test it:
var a =[BigDataMock],
url = "http://localhost:8084/jerseyrangeplan/rest/excel/export"
$.ajax({
url: url,
method: 'post',
crossDomain: true,
contentType: "application/json",
dataType: "json",
data:{
content: JSON.stringify(a)
},
success: function(result, status, xhr) {
window.location.assign(url + "?fileName=" + result.fileName);
},
error: function (responseData, textStatus, errorThrown) {
console.log('POST failed.');
}
});
What I want to do is basically extract a big dataset that is in the frontend to Excel and then download the file. I allready tried the form approach but it worked only for small datasets. We have 10000 members in the object and the form cutted the stringyfied string which lead to problems in the backend. I also tried to use excelbuilder.js, that didn't work either. The bytestream I was sending after generating the excel file wasn't interpreted correctly from the Java backend. Now I want to save the excel file and then instantly trigger a download in the callback.
But I keep getting the 415 unsupported media type error. I also have trouble with CORS filter which seems not to work correctly.
Can anybody help?
Thanks in advance,
Sebastian