I'm trying to create a Web Service that consumes an HTML which is later used to create a PDF with iText.
I'm using Postman in order to send my requests to server but everytime I get the following error, no matter which content type I select:
{
"status": "CONFLICT",
"code": 40902,
"message": "Content type 'text/plain' not supported",
"developerMessage": "null",
"moreInfoUrl": "class org.springframework.web.HttpMediaTypeNotSupportedException",
"throwable": null
}
The message changes depending on the content type selected:
"message": "Content type 'text/xml' not supported"
"message": "Content type 'text/html' not supported"
This is my endpoint:
@RequestMapping(path = "/reports/pdf", method = RequestMethod.POST, consumes = MediaType.TEXT_HTML_VALUE)
public ResponseEntity<byte[]> generatePdfReport(@RequestBody String html) throws Exception {
byte[] pdfBytes = reportsService.generatePdf(html);
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(pdfBytes, HttpStatus.OK);
return response;
}
I've changed consumes
attribute to:
MediaType.TEXT_PLAIN_VALUE
MediaType.TEXT_XML_VALUE
to match what I'm sending on Postman.
As well as per @dnault comment, removing it completely from the RequestMapping
annotation with the same results.
I've looked into similar questions:
- Content type 'text/plain;charset=UTF-8' not supported error in spring boot inside RestController class This is the closest one to my problem, but I'm already setting my content type in the request to the same one I expect on the endpoint.
- Error org.springframework.web.HttpMediaTypeNotSupportedException
- Error: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain;charset=UTF-8' not supported
However none of the above and some others that aren't really close to my problem that I've checked already provide an answer that solves this issue.
The sample HTML I'm trying to send to server is:
<table style="border: 1px solid black; font-size: 12px; margin-top: 1px; width: 900px;" id="table_direction">
<tr>
<td width="33%" colspan="2">
<strong>Data1</strong>
</td>
<td width="33%" colspan="2">
<strongData2</strong>
</td>
<td width="16%" colspan="1">Foo</td>
<td width="16%" colspan="1">Bar</td>
</tr>
<tr>
<td colspan="">ID</td>
<td colspan="">123456</td>
<td colspan="">Property 1</td>
<td colspan="">Foo</td>
<td colspan="">Property 2</td>
<td colspan="">Bar</td>
</tr>
</table>
Our configuration is made by Java configuration classes which are as follows:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.company.project")
@PropertySource("classpath:application.properties")
@EnableTransactionManagement // proxyTargetClass = true
@EnableJpaRepositories(basePackages = { "com.company.project.dao", "com.company.project.repository" })
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter {
@Inject
Environment env;
@Value("${jdbc.user}")
private String userDB;
@Value("${jdbc.password}")
private String passDB;
@Value("${jdbc.url}")
private String urlDB;
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
@Bean(name = "dataSource")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName(driverClassName);
driverManagerDataSource.setUrl(urlDB);
driverManagerDataSource.setUsername(userDB);
driverManagerDataSource.setPassword(passDB);
return driverManagerDataSource;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.company.project.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
entityManagerFactoryBean.setPackagesToScan("com.company.project.model");
entityManagerFactoryBean.setJpaProperties(hibernateProperties());
return entityManagerFactoryBean;
}
private Properties hibernateProperties() {
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
jpaProperties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
return jpaProperties;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
@Bean(name = "transactionManager2")
@Autowired
@Named("transactionManager2")
public HibernateTransactionManager transactionManager2(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
return vendorAdapter;
}
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
Hibernate5Module module = new Hibernate5Module();
module.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
mapper.registerModule(module);
messageConverter.setObjectMapper(mapper);
return messageConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}
}
@ControllerAdvice
public class GenericRepositoryRestExceptionHandler extends RepositoryRestExceptionHandler {
@Autowired
public GenericRepositoryRestExceptionHandler(MessageSource messageSource) {
super(messageSource);
// TODO Auto-generated constructor stub
}
@ResponseBody
@ExceptionHandler(Exception.class)
ResponseEntity<?> handleException(Exception e) {
// return response(HttpStatus.CONFLICT, 40902, e.getMessage());
return response(HttpStatus.CONFLICT, 40902, e.getMessage(), e.getCause() + "", e.getClass() + "");
}
private ResponseEntity<RestError> response(HttpStatus status, int code, String msg) {
return response(status, code, msg, "", "");
}
private ResponseEntity<RestError> response(HttpStatus status, int code, String msg, String devMsg, String moreInfo) {
return new ResponseEntity<>(new RestError(status, code, msg, devMsg, moreInfo, null), status);
}
}
public class CORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
System.out.println("Filtering on...........................................................");
SecurityContext ctx = SecurityContextHolder.getContext();
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
consumes
attribute from theRequestMapping
annotation? – Fructuous