Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: - spring

I am trying to expose REST service, but while hitting it from POSTMAN i am getting below :
WARNING: Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class java.util.ArrayList
Where as i have also included below jar files which are required :
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.1</version>
</dependency>
Here is my REST controller Code :
#RestController
#RequestMapping("/MayankAPI")
public class TestRestAPI {
#RequestMapping(value="/sayHello" , method = RequestMethod.POST)
public TestPojo postData(#RequestBody String payload) {
System.out.println("Hello post"+payload);
TestPojo payload1=new TestPojo();
payload1.setStudentName("Jack");
return payload1;
}
#RequestMapping(value="/sayHello" , method = RequestMethod.GET)
public List<TestPojo> getData(String payload) {
System.out.println("Hello get"+payload);
List<TestPojo> payload1=new ArrayList<TestPojo>();
TestPojo tp = new TestPojo();
tp.setStudentName("Jack");
payload1.add(tp);
return payload1;
}
Here is my bean which i am trying to return :
public class TestPojo {
private String studentName;
private String studentId;
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
}
Please help me where i am doing wrong.

I know it too late but still
Alternate Solution:
you need to enable Spring project as Web MVC as follow:
#Configuration
#EnableWebMvc
#ComponentScan("basePackages = com.test")
public class MiBenefitConfiguration
{
}

This is happening because MappingJackson2HttpMessageConverter is not registered in my App config file as below.
#Configuration
#ComponentScan("basePackages = com.test")
public class MiBenefitConfiguration extends WebMvcConfigurationSupport{
#Bean
public ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
#Bean
public MappingJackson2HttpMessageConverter messageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(getObjectMapper());
return converter;
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(messageConverter());
addDefaultHttpMessageConverters(converters);
}
}

Related

Deprecated methods when using Feign with Oauth2 in SpringBoot 2.4.3

I am trying to use feign client with Oauth2 in my project based in Springboot 2.4.3. I implemented this example but the DefaultOAuth2ClientContext, OAuth2ProtectedResourceDetails and ClientCredentialsResourceDetails methods are deprecated.
pom.xml
<dependencies>
....
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
....
</dependencies>
application.yml
config:
serverUrl : exampleUrl
clientId: exampleClientId
clientSecret: exampleClientSecret
scopes: exampleScopes
feign:
post:
name: postService
url: https://localhost:8102/post
get:
name: getService
url: https://localhost:8102/get
FeignClient.java
#FeignClient(name = "example", configuration = OAuth2ClientConfig.class)
public interface FeignClient {
#PostMapping(value = "${feign.post.url}")
HttpEntity search(#PathVariable String id);
#GetMapping(value = "${feign.get.url}")
HttpEntity upload(#PathVariable String id);
}
OAuth2ClientProperties.java
#ConfigurationProperties(prefix = "config")
public class OAuth2ClientProperties {
private String serverUrl;
private String clientId;
private String clientSecret;
private List<String> scopes = new ArrayList<>();
public String getAccessTokenUri() {
return serverUrl;
}
public void setAccessTokenUri(String accessTokenUri) {
this.serverUrl = accessTokenUri;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public List<String> getScopes() {
return scopes;
}
public void setScopes(List<String> scopes) {
this.scopes = scopes;
}
}
OAuth2ClientConfig.java
import feign.RequestInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
#Configuration
#EnableConfigurationProperties(OAuth2ClientProperties.class)
public class OAuth2ClientConfig {
#Autowired
private OAuth2ClientProperties oAuth2ClientProperties;
#Bean
public RequestInterceptor requestInterceptor() {
return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(),
oAuth2ProtectedResourceDetails());
}
private OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails() {
ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
details.setClientId(oAuth2ClientProperties.getClientId());
details.setClientSecret(oAuth2ClientProperties.getClientSecret());
details.setAccessTokenUri(oAuth2ClientProperties.getAccessTokenUri());
details.setScope(oAuth2ClientProperties.getScopes());
return details;
}
}
I have not yet tested whether it works or not, but what bothers me is having deprecated methods and I have not found a solution to replace them with equivalents taken into account by the new version.
Any ideas ?

How to create filter in Spring RESTful for Prevent XSS?

i use from Spring 4.2.6.RELEASE and backend is rest services.
and now I can not have a filter for Prevent XSS
my filter is:
#Component
#Order(1)
public class XSSFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void destroy() {
}
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
}
}
and XSSRequestWrapper is :
public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
#Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = stripXSS(values[i]);
}
return encodedValues;
}
#Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
return stripXSS(value);
}
#Override
public String getHeader(String name) {
String value = super.getHeader(name);
return stripXSS(value);
}
private String stripXSS(String value) {
return StringEscapeUtils.escapeHtml(value);
}
}
and in WebConfig extends WebMvcConfigurerAdapter Class:
// -----------------------------------------------------
// Prevent XSS
// -----------------------------------------------------
#Bean
public FilterRegistrationBean xssPreventFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new XSSFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
My Rest Class is:
#RestController
#RequestMapping("/personService")
public class PersonController extends BaseController<PersonDto, PersonCriteria> {
#RequestMapping( value= "/test" )
private void getTest2(#RequestParam String name) {
System.out.println(name);
System.out.println( StringEscapeUtils.escapeHtml(name) );
}
}
But it does not work, without any Error or Exception.
How can I do this and create my own filter? I use only Java Config and no XML.
in my Controller I was forced again use StringEscapeUtils.escapeHtml(name) and this is bad.
I’ve created a fully executable sample project based on your codes.
Everything goes fine, you can download full source from my github https://github.com/mehditahmasebi/spring/tree/master/spring-xss-filter and for running command “mvnw spring-boot:run” and in browser type: http://localhost:8080/personService/test?name=foobar, so you can see result in XSSRequestWrapper.stripXSS.
I hope this source code will help you.
Some explanation :
Project structure :
POM.xml
WebConfig.java for Spring web config
SpringBootApplication.java for starting up application
your classes (PersonController.java, XSSFilter.java and XSSRequestWrapper.java)
dive into them, but I was only copy important lines :
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
WebConfig.java (at the bottom lines you can see your bean) :
#Configuration
#EnableWebMvc
#EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll()
.and().csrf().disable();
}
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedMethods("GET, POST, PATCH, PUT, DELETE, OPTIONS")
.allowedOrigins("*");
}
#Bean
public FilterRegistrationBean xssPreventFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new XSSFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
SpringBootApplication.java (for starting up project) :
#SpringBootApplication
public class SpringbootApplication extends SpringBootServletInitializer {
/**
* tomcat deployment needed
*/
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringbootApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
System.out.println("Spring boot application started!");
}
}
The other java source files is exactly as you are , but with 2 changes :
first, I've added a sysout line to see trace of your code without debugging:
private String stripXSS(String value) {
if(value != null)
System.out.println("escapeHTML work successfully and escapeHTML value is : " + StringEscapeUtils.escapeHtml(value));
return StringEscapeUtils.escapeHtml(value);
}
and the second change is, I commented escapeHtml from PersonController as you said is not a good idea:
#RequestMapping( value= "/test" )
private void getTest2(#RequestParam String name) {
System.out.println(name);
// System.out.println( StringEscapeUtils.escapeHtml(name) );
}
You can find all the source at my github https://github.com/mehditahmasebi/spring/tree/master/spring-xss-filter

Swagger configured in Spring Boot shows only methods with POST and GET mapping

Swagger configured in Spring Boot shows only one method with POST mapping and one method with GET mapping from every controller. Swagger ignores another methods with GET and POST mapping and ignores all methods with PUT and DELETE mappings. My configuration:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("my.project.controllers"))
.paths(PathSelectors.ant("/api/*"))
.build();
}
}
Dependency in pom.xml:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
My controllers code:
#RestController
#RequestMapping(value = "/api/users", produces = "application/json; charset=UTF-8")
public class UserController {
#Autowired
private UserService userService;
protected UserService getService() {
return userService;
}
#RequestMapping(method = GET)
public Page<User> query(#RequestParam Map<String, Object> parameters, Pageable pageable) {
return getService().query(parameters, pageable);
}
#ResponseStatus(CREATED)
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity<User> create(#RequestBody User entity) {
return ResponseEntity.status(HttpStatus.CREATED).body(getService().create(entity));
}
#RequestMapping(value = "/{id:[0-9]+}", method = RequestMethod.PUT)
public ResponseEntity<User> update(#PathVariable Long id, #RequestBody User entity) {
return ResponseEntity.ok(getService().update(id, entity));
}
#RequestMapping("/current")
public ResponseEntity current() {
return ResponseEntity.ok(userService.getUser());
}
#ResponseStatus(HttpStatus.OK)
#RequestMapping(value = "/{id:[0-9]+}/enable", method = RequestMethod.POST)
public void enable(#PathVariable("id") final long id) {
userService.enable(id);
}
#ResponseStatus(HttpStatus.OK)
#RequestMapping(value = "/{id:[0-9]+}/disable", method = RequestMethod.POST)
public void disable(#PathVariable("id") final long id) {
userService.disable(id);
}
#RequestMapping(value = "/histories", method = RequestMethod.GET)
public List<UserHistory> histories() {
return userService.histories();
}
}
May be i need add some more configuration or add something else?
Based on your controller, I think you should add one more star in the path matcher in your swagger config:
.paths(PathSelectors.ant("/api/**"))
e.g /api/users/current would not be matched by the /api/* but by /api/**, and this why you are getting only the base path endpoints documented.

Hystrix Javanica fallback not working in Spring Cloud 1.0

I built a super simple Hystrix short circuit example based on #spencergibb feign-eureka spring cloud starter example. At first I thought I couldn't get the hystrix javanica default fallbackMethod to trigger due to feign.. now, removing feign, the hystrix default fallbackMethod still doesn't catch exceptions.
pom.xml
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>1.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
:
</dependencies>
Main file:
#SpringBootApplication
#EnableDiscoveryClient
#EnableHystrix
#RestController
public class HelloClientApplication {
#Autowired
HelloClientComponent helloClientComponent;
#RequestMapping("/")
public String hello() {
return helloClientComponent.makeMultipleCalls();
}
public static void main(String[] args) {
SpringApplication.run(HelloClientApplication.class, args);
}
}
HelloClientComponent.java (created because I know javanica expects to be inside a spring managed component or service):
#Component
public class HelloClientComponent {
#Autowired
RestTemplate restTemplate;
public String makeMultipleCalls() {
int cnt=20;
StringBuilder sb = new StringBuilder();
while (cnt-- > 0) {
String response = theServerRequestRoot();
sb.append(response).append(" ");
}
return sb.toString();
}
public String theServersRequestRootFallback() {
System.out.println("BOMB!!!!!!");
return "BOMB!!!!!!";
}
#HystrixCommand(fallbackMethod = "theServersRequestRootFallback", commandKey = "callToServers")
public String theServerRequestRoot() {
ResponseEntity<String> result = restTemplate.getForEntity("http://HelloServer", String.class);
System.out.println(result.getBody());
return result.getBody();
}
}
I start 2 servers, one which always succeeds and responds, and the other will fail 30% of the time with a 500 error. When I curl this client (to '/') things go normally for the non-forced failure calls. Round robining works fine as well. When the second server does return the 500 error, the fallbackMethod does not get called and the curl to '/' ends and returns with an error.
Update with solution per Spencer and Dave's suggestions. Change to the following:
Main Application file:
#SpringBootApplication
#EnableDiscoveryClient
#EnableHystrix
#RestController
public class HelloClientApplication {
#Autowired
HelloClientComponent helloClientComponent;
#RequestMapping("/")
public String hello() {
int cnt=20;
StringBuilder sb = new StringBuilder();
while (cnt-- > 0) {
String response = helloClientComponent.theServerRequestRoot(); // call directly to #Component in order for #HystrixCommand to intercept via AOP
sb.append(response).append(" ");
}
return sb.toString();
}
public static void main(String[] args) {
SpringApplication.run(HelloClientApplication.class, args);
}
}
HelloClientComponent.java:
#Component
public class HelloClientComponent {
#Autowired
RestTemplate restTemplate;
public String theServersRequestRootFallback() {
System.out.println("BOMB!!!!!!");
return "BOMB!!!!!!";
}
#HystrixCommand(fallbackMethod = "theServersRequestRootFallback", commandKey = "callToServers")
public String theServerRequestRoot() {
ResponseEntity<String> result = restTemplate.getForEntity("http://HelloServer", String.class);
System.out.println(result.getBody());
return result.getBody();
}
}
#HystrixCommand only works because Spring makes a proxy to call that method on. If you call the method from within the proxy it doesn't go through the interceptor. You need to call the #HystrixCommand from another #Component (or use AspectJ).

Dependency Injection in JSR-303 Constraint Validator with Spring fails

I have the same problem as here and here but couldn't find a solution yet.
So my sample test project will show the whole relevant configuration and code:
Constraint annotation:
#Target({ ElementType.METHOD, ElementType.FIELD })
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = FooValidator.class)
public #interface FooValid {
String message();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Annotated PoJo:
public class Foo {
#FooValid(message = "Test failed")
private Integer test;
[...]
}
Annotated Service with #Validated:
#Service
#Validated
public class FooService {
private final Test test;
#Autowired
public FooService(final Test test) {
this.test = test;
}
public void foo(#Valid final Foo foo) {
this.test.test(foo);
}
}
JSR-303 ConstraintValidator:
public class FooValidator implements ConstraintValidator<FooValid, Integer> {
#Autowired
private ValidationService validationService;
#Override
public void initialize(final FooValid constraintAnnotation) {
// TODO Auto-generated method stub
}
#Override
public boolean isValid(final Integer value, final ConstraintValidatorContext context) {
// this.validationService is always NULL!
Assert.notNull(this.validationService, "the validationService must not be null");
return false;
}
}
Injected ValidationService:
#Service
public class ValidationService {
public void test(final Foo foo) {
System.out.println(foo);
}
}
Spring boot application and configuration:
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
final ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
final FooService service = context.getBean(FooService.class);
service.foo(new Foo());
}
#Bean
public static LocalValidatorFactoryBean validatorFactory() {
return new LocalValidatorFactoryBean();
}
#Bean
public static MethodValidationPostProcessor validationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
relevant maven pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.9.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.Application</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I'm using the LocalValidatorFactoryBean with the default SpringConstraintValidatorFactory.
But why the dependency injection is not working in the ConstraintValidator and the ValidationService could not be autowired?
By the way if I don't use #Validated at the service, inject in opposite the spring or javax Validator interface and call manually "validator.validate" the dependency injection will work. But I don't want to call the validate method in every service manually.
Many thanks for help :)
I have fought the same problem in Spring Boot environment and I found out that Hibernate internal implementation got in instead of the configured Spring's one. When the application started, debugger caught a line with the Spring's factory but later in runtime there was Hibernate's one. After some debugging, I came to the conclusion that MethodValidationPostProcessor got the internal one. Therefore I configured it as follows:
#Bean
public Validator validator() {
return new LocalValidatorFactoryBean();
}
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor(Validator validator) {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator);
return methodValidationPostProcessor;
}
Note the setter for validator - it did the job.
I had the same issue. The problem is arises because Hibernate is finding and applying the validators instead of Spring. So you need to set validation mode to NONE when configuring Hibernate:
#Bean(name="entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
localContainerEntityManagerFactoryBean(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean lcemfb =
new LocalContainerEntityManagerFactoryBean();
lcemfb.setDataSource(dataSource);
lcemfb.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
lcemfb.setValidationMode(ValidationMode.NONE);
// Continue configuration...
If you have confgured a LocalValidationFactoryBean Spring will pick up any validators annotated with #Component and autowire them.
This is what worked for me. I had to used the #Inject tag.
public class FooValidator implements ConstraintValidator<FooValid, Integer> {
private ValidationService validationService;
#Inject
public FooValidator(ValidationService validationService){
this.validationService = validationService;
}
#Override
public void initialize(final FooValid constraintAnnotation) {
// TODO Auto-generated method stub
}
#Override
public boolean isValid(final Integer value, final ConstraintValidatorContext context) {
// this.validationService is always NULL!
Assert.notNull(this.validationService, "the validationService must not be null");
return false;
}
}

Resources