当前,我具有将数据从MYSQL转换为CSV的功能。 CSV函数包含使用viewResolver的webconfig。问题是,当我使用以下功能时,页面无法查看,但可以下载CSV文件,反之亦然。我需要配置什么吗?
-配置ContentNegotiatingViewResolver
@Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<>();
resolvers.add(csvViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
WebConfig-完整代码
package com.portal.dmtt.csvDownload.config;
import com.portal.dmtt.csvDownload.viewResolver.CsvViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true);
}
/*
* Configure ContentNegotiatingViewResolver
*/
@Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<>();
resolvers.add(csvViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
/*
* Configure View resolver to provide Csv output using Super Csv library to
* generate Csv output for an object content
*/
@Bean
public ViewResolver csvViewResolver() {
return new CsvViewResolver();
}
}
导出控制器
package com.portal.dmtt.csvDownload.controller;
import com.portal.dmtt.repo.dmttDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ExportController {
@Autowired
private dmttDAO dmttDAO;
/**
* Handle request to download an Excel document
*/
@GetMapping("/dl")
public String download(Model model) {
model.addAttribute("results", dmttDAO.getAllResultSet());
return "";
}
}
摘要视图
package com.portal.dmtt.csvDownload.view;
import org.springframework.web.servlet.view.AbstractView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
public abstract class AbstractCsvView extends AbstractView {
private static final String CONTENT_TYPE = "text/csv";
public AbstractCsvView() {
setContentType(CONTENT_TYPE);
}
@Override
protected boolean generatesDownloadContent() {
return true;
}
@Override
protected final void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType(getContentType());
buildCsvDocument(model, request, response);
}
protected abstract void buildCsvDocument(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
CSV视图
package com.portal.dmtt.csvDownload.view;
import com.portal.dmtt.model.exceptionMonitoring.FN_Result_Set;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
public class CsvView extends AbstractCsvView {
@Override
protected void buildCsvDocument(Map<String, Object> model, HttpServletRequest request, HttpServletResponse
response) throws Exception {
response.setHeader("Content-Disposition", "attachment; filename=\"my-csv-file.csv\"");
List<FN_Result_Set> fnResultSetList = (List<FN_Result_Set>) model.get("results");
String[] header = {"SP_ID", "SP_ID", "XFER_XMIT_STATUS", "XFER_FILE_NAME", "UPDATE_TS", "YYMM", "REMARKS"};
try {
ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
CsvPreference.STANDARD_PREFERENCE);
csvWriter.writeHeader(header);
for (FN_Result_Set user : fnResultSetList) {
csvWriter.write(user, header);
}
csvWriter.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
查看解析器
package com.portal.dmtt.csvDownload.viewResolver;
import com.portal.dmtt.csvDownload.view.CsvView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import java.util.Locale;
public class CsvViewResolver implements ViewResolver {
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return new CsvView();
}
}
答案 0 :(得分:0)
问题之一是您的CSVViewResolver正在解析任何视图名称的视图。如果视图名称null
不为空,则可能要从CSVViewResolver.resolveViewName()
返回s
。
另一个问题是浏览器(至少是我的Chrome)不会发送text/csv
作为Accept标头,而是发送text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
在configureContentNegotiation
中为CSV明确设置媒体类型:
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true)
.mediaType("csv", MediaType.parseMediaType("text/csv"));
}
删除Bean contentNegotiatingViewResolver
您不应创建一个contentNegotiatingViewResolver
,因为Spring Boot提供了一个。如果提供一个,则将有两个这种类型,而您将没有Thymeleaf ViewResolver。由于您的CSVViewResolver
将返回任何视图名称的视图,因此该视图将在您提供的ContentNegotiatingViewResolver
中解析,而不是在Spring提供的视图中解析。
详细信息:
Spring Boot的csvViewResolver
将与ContentNegotiatingViewResolver
,BeanNameViewResolver
,ThymeleafViewResolver
,ViewResolverComposite
等其他对象一起拾取InternalResourceViewResolver
bean。
要对此进行调试,请在DispatcherServlet.resolveViewName
上设置一个断点:
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}