Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Spring MVC return CSV as convenient as return JSON

I know Spring MVC could return a model in format of Json easily; however, I have tried quite different approaches to return a model in CSV format (via Jackson), but could not make it successfully.

What should I do?

I enclose my model code, controller code, and gradle.build as following:

Thanks a lot!

Model:

@JsonPropertyOrder({ "staffName", "name" })
public class Greeter
{
    String name;
    String staffName[];

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String[] getStaffName()
    {
        return staffName;
    }

    public void setStaffName(String[] staffName)
    {
        this.staffName = staffName;
    }
}

Controller:

@Controller
public class GreetingController {

    @RequestMapping(value = "/greeter/json", method = RequestMethod.GET)
    public @ResponseBody
    Greeter getGreeterInJSON() {

        Greeter greeter = new Greeter();

        greeter.setName("default");
        greeter.setStaffName(new String[] { "ye", "lichi" });

        return greeter;

    }

    @RequestMapping(value = "/greeter/csv", method = RequestMethod.GET, consumes = "text/csv")
    public @ResponseBody
    Greeter getGreeterInCSV(HttpServletResponse response) {
        Greeter greeter = new Greeter();

        greeter.setName("default");
        greeter.setStaffName(new String[] { "ye", "lichi" });

        CsvMapper mapper = new CsvMapper();
        CsvSchema schema = mapper.schemaFor(Greeter.class);

        ObjectWriter writer = mapper.writer(schema.withLineSeparator("\n"));

        File greeterCSV = new File("greeterCSV.csv");

        try {
            writer.writeValue(greeterCSV, greeter);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return greeter;
    }
}

build.gradle dependencies:

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'

    compile ('org.springframework:spring-context:4.0.0.RELEASE')
    compile("org.springframework.boot:spring-boot-starter-web:0.5.0.M6")
    compile("org.thymeleaf:thymeleaf-spring3:2.0.17")

    // compile "org.codehaus.jackson:jackson-mapper-asl:1.9.13"
    compile 'com.fasterxml.jackson.core:jackson-databind:2.3.0'
    compile 'com.fasterxml.jackson.core:jackson-core:2.3.0'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.3.0'

    compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.3.0'

    testCompile group: 'junit', name: 'junit', version: '4.+'
    testCompile "org.mockito:mockito-all:1.9.5"
}

Edit:


Tomcat error:

HTTP Status 415 -

type Status report

message

description The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.

like image 905
Ye Huang Avatar asked Jan 05 '14 19:01

Ye Huang


People also ask

How do I get API response in CSV format?

There is no function in the API that will return results in CSV format. You will need to use language-level utilities to create a CSV file while generating the reports.

How would you approach loading and parsing the CSV using spring?

To upload and parse a CSV file in Spring Boot, you only need the spring-boot-starter-web and opencsv dependencies. Additionally, we also need spring-boot-starter-thymeleaf for serving Thymeleaf templates. The OpenCSV 3rd-party library will be used for parsing the uploaded CSV file.


1 Answers

You want not to consume but produce csv. The way you have it, the service expects the input to be provided in csv format, that's why it complains about 'request entity is in a format not supported'. Key is 'request' here - it expects some input in csv format. Changing 'consume' to 'produces' should fix your problem.

like image 79
Sergey Melnik Avatar answered Oct 19 '22 20:10

Sergey Melnik