如何让Spring控制器从POJO返回CSV? [英] How to make Spring Controller to return CSV from a POJO?

查看:180
本文介绍了如何让Spring控制器从POJO返回CSV?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个简单的Java对象:

Given a simple Java Object:

public class Pojo {
    private String x;
    private String y;
    private String z;

    //... getters/setters ...
}

有一些库,我可以把我的项目,将使一个控制器这样:

Is there some lib that i can put on my project that will make a controller like this:

@RequestMapping(value="/csv", method=RequestMethod.GET, produces= MediaType.TEXT_PLAIN)
@ResponseBody
public List<Pojo> csv() {
    //Some code to get a list of Pojo objects
    //...

    return myListOfPojos;
}

要生成我的Pojos的csv文件?对于Json结果,我使用Jackson lib。基于另一个问题,我为Tsv回应做了我自己的HTTPMessageConverter。

To produce a csv file of my Pojos? For a Json result, i use Jackson lib. I need another lib for CSV results.

推荐答案

>

TsvMessageConverter.java



Based on another question, i did my own HTTPMessageConverter for Tsv Responses.

public class TsvMessageConverter extends AbstractHttpMessageConverter<TsvResponse> {

    public static final MediaType MEDIA_TYPE = new MediaType("text", "tsv", Charset.forName("utf-8"));
    private static final Logger logger = LoggerFactory.getLogger(TsvMessageConverter.class);

    public TsvMessageConverter() {
        super(MEDIA_TYPE);
    }

    protected boolean supports(Class<?> clazz) {
        return TsvResponse.class.equals(clazz);
    }

    @Override
    protected TsvResponse readInternal(Class<? extends TsvResponse> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }

    protected void writeInternal(TsvResponse tsvResponse, HttpOutputMessage output) throws IOException, HttpMessageNotWritableException {
        output.getHeaders().setContentType(MEDIA_TYPE);
        output.getHeaders().set("Content-Disposition", "attachment; filename=\"" + tsvResponse.getFilename() + "\"");
        final OutputStream out = output.getBody();

        writeColumnTitles(tsvResponse, out);

        if (tsvResponse.getRecords() != null && tsvResponse.getRecords().size() != 0) {
            writeRecords(tsvResponse, out);
        }

        out.close();
    }

    private void writeRecords(TsvResponse response, OutputStream out) throws IOException {
        List<String> getters = getObjectGetters(response);
        for (final Object record : response.getRecords()) {
            for (String getter : getters) {
                try {
                    Method method = ReflectionUtils.findMethod(record.getClass(), getter);
                    out.write(method.invoke(record).toString().getBytes(Charset.forName("utf-8")));
                    out.write('\t');
                } catch (IllegalAccessException | InvocationTargetException e) {
                    logger.error("Erro ao transformar em CSV", e);
                }
            }
            out.write('\n');
        }
    }

    private List<String> getObjectGetters(TsvResponse response) {
        List<String> getters = new ArrayList<>();
        for (Method method : ReflectionUtils.getAllDeclaredMethods(response.getRecords().get(0).getClass())) {
            String methodName = method.getName();
            if (methodName.startsWith("get") && !methodName.equals("getClass")) {
                getters.add(methodName);
            }
        }
        sort(getters);
        return getters;
    }

    private void writeColumnTitles(TsvResponse response, OutputStream out) throws IOException {
        for (String columnTitle : response.getColumnTitles()) {
            out.write(columnTitle.getBytes());
            out.write('\t');
        }
        out.write('\n');
    }
}



TsvResponse.java



TsvResponse.java

public class TsvResponse {
   private final String filename;
   private final List records;
    private final String[] columnTitles;

   public TsvResponse(List records, String filename, String ... columnTitles) {
       this.records = records;
       this.filename = filename;
       this.columnTitles = columnTitles;
   }
   public String getFilename() {
       return filename;
   }
   public List getRecords() {
       return records;
   }

    public String[] getColumnTitles() {
        return columnTitles;
    }
}

在SpringContext.xml中添加以下内容:

And on SpringContext.xml add the following:

<mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="com.mypackage.TsvMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

因此,您可以像这样在控制器上使用:

So, you can use on your controller like this:

@RequestMapping(value="/tsv", method= RequestMethod.GET, produces = "text/tsv")
    @ResponseBody
    public TsvResponse tsv() {
        return new TsvResponse(myListOfPojos, "fileName.tsv",
                "Name", "Email", "Phone", "Mobile");
    }

这篇关于如何让Spring控制器从POJO返回CSV?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆