Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.List] and content type [text/html] - spring-boot

I'm trying to call other service from my spring boot application.
Employee class
public class Employee {
private int id;
private String name;
private String email;
private String gender;
private String status;
// Constructor, getters & setters
}
Below is my Rest controller code
#GetMapping("/getUsers")
public List<Employee> getUsers() {
RestTemplate restTemplate = new RestTemplate();
String resourceUrl = "http://gorest.co.in/public/v2/users";
ResponseEntity<List> response = restTemplate.getForEntity(resourceUrl, List.class);
List<Employee> items = response.getBody();
return items;
}
I tried adding different response type but I always get below error
org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.List] and content type [text/html]

Resttemplate no support the response of 'content type [text/html;charset=UTF-8]'.
solution:
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(
MediaType.TEXT_HTML,
MediaType.TEXT_PLAIN));

Related

How to retrieve XML using webClient in Spring?

I've been trying to retrieve XML using webClient in Spring, but is has not worked out.
I've been getting this error message.
UnsupportedMediaTypeException: Content type 'application/xml;charset=UTF-8' not supported for bodyType
I think the request was ok, but I failed to get the response as an object. I got '200 ok' from the server.
And I tried to send a request with 'Talend API Tester' to see if I made a right one, I got perfect response.
And I had added '#XmlRootElement', '#XmlAttribute's to my DTO.
But, I only had gotten an empty List '[]'.
What should I do to solve this problem?
Here are my codes.
//Service
public List<SearchResponseDto> search(SearchRequestDto searchRequestDto) {
System.out.println(requestUrl);
var uri = UriComponentsBuilder.fromUriString(requestUrl)
.queryParams(searchRequestDto.toMultiValueMap())
.build()
.encode()
.toUri();
return WebClient.create()
.get()
.uri(uri)
.accept(MediaType.APPLICATION_XML)
.headers(head -> {
head.set("X-Naver-Client-Id", naverId);
head.set("X-Naver-Client-Secret", naverSecret);
})
.retrieve()
.bodyToFlux(SearchResponseDto.class)
.toStream()
.collect(Collectors.toList());
}
//responseDTO
#Data
#NoArgsConstructor
#AllArgsConstructor
public class SearchResponseDto {
private String lastBuildDate;
private int total;
private int start;
private int display;
private List<SearchItem> item;
#Data
#NoArgsConstructor
#AllArgsConstructor
public static class SearchItem {
private String title;
private String link;
private String image;
private String author;
private int price;
private int discount;
private String publisher;
private String isbn;
private String description;
private String pubdate;
}
}
You need to configure additional codec to deserialize Xml response
WebClient.builder()
.exchangeStrategies(
ExchangeStrategies.builder()
.codecs(configurer ->
configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder())
)
.build()
)
.build();

How to change the field name in a request body of feign client?

I have a feign client that uses a dto to perform the request using #RequestBody. The problem is that some property does not match with the java standards, for example id_client. Is there a way to change the variable name and keep it working with the feign ?
Below there is the code of the feign client the dto used in the request body.
#FeignClient(name="sso-token", url = "http://keycloak.com.br:8180", path="/")
public interface SsoTokenQueryWebAdapter {
#PostMapping(value = "/auth/realms/real-refrigerantes/protocol/openid-connect/token", consumes = "application/x-www-form-urlencoded")
public String recuperarToken(#RequestBody RequestTokenDto dto);
}
#Data
public class RequestTokenDto {
private String username;
private String password;
private String client_id;
private String client_secret;
private String grant_type;
}

Spring MVC Based Rest Services Validations for request body

I have Rest Controller in my application which has the code snippet like below:-
#RestController
#RequestMapping("/api/v1/user")
public class UserRestControllerV1 {
#PostMapping("")
public Response registerUser(#RequestBody #Valid final Request<UserDto> request,
final HttpServletRequest httpServletRequest,
BindingResult result){
Response response = new Response(request);
if(result.hasErrors()){
response.setData(new String("Error"));
}else {
response.setData(new String("Test"));
}
return response;
}
The Request Class:-
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Request<T> {
#JsonProperty(value = "co-relation-id")
private String coRelationID;
#NotNull(message = "The request body should be present")
private T data;
/*
..... various other fields
Getters / Setters
*/
}
The UserDto Class :-
public class UserDto {
#NotNull(message = "The username should not be null")
private String username;
#NotNull(message = "The password should not be null")
#JsonIgnore
private String password;
/*
..... various other fields
Getters / Setters
*/
}
Issue : I am having issues with my validations here. The field private T data in the request class gets validated but the fields inside T - in the case UserDto are not getting validated.
So I need to know the approach or code snippet to achieve this.
I have tried configuring the hibernate validator bean in the configuration but it is of no help in the scenario
#Valid constraint will instruct the Bean Validator to delve to the type of its applied property and validate all constraints found there.
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Request<T> {
#JsonProperty(value = "co-relation-id")
private String coRelationID;
//#NotNull(message = "The request body should be present")
#Valid
private T data;
/*
..... various other fields
Getters / Setters
*/
}

How to create REST endpoint service consume multipart using Spring 4.x?

I am trying to create a REST service that consumes the "multipart/form-data" with text and attachment objects. For files i can use "org.springframework.web.multipart.MultipartFile", but how do i specify the service method for Text objects?
Below is the expected client call to service.
create Rest endpoint by using this way
public void sendEmail(#RequestParam String to,#RequestParam String from,#RequestParam String cc,#RequestParam String body, #RequestParam(required = false)MultipartFile[] file){
}
or
create pojo class for strings
public class Email{
private String from;
private String to;
private String cc;
private String body;
// getters and setters
}
//email should be json string
public void sendEmail(#RequestParam String email,#RequestParam(required = false) MultipartFile[] file){
ObjectMapper mapper=new ObjectMapper();
Email email_pojo=mapper.readValue(email,Email.class);
}
Just create the controller as specified below:
#RequestMapping(value = "/uploadFiles", headers = ("content-type=multipart/*"), method = RequestMethod.POST)
public AppDTO uploadFile(UploadFiles uploadFiles, HttpServletRequest request) {
Now create a pojo class for what ever things you need to submit along with a multipartfile member where the file will bind to. refer below code for pojo
class UploadFiles
{
private String cc;
private String to;
private String from;
private MultipartFile attachment;
//create getters and setters
}
MultipartFile here used is provided by spring
import org.springframework.web.multipart.MultipartFile;
If you have more than one attachment you can use MultipartFile[] in POJO

Spring Request Mapping post vs put, same method, same logic, but

I have a 2 method:
first one create product:
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> create(#Validated ProductDTO productDTO){
productService.addProduct(productDTO);
return new ResponseEntity<>("Maxsulot ro'yhatga qo'shildi", HttpStatus.OK);
}
another one update product:
#RequestMapping(method = RequestMethod.PUT)
public ResponseEntity<?> update(#Validated ProductDTO productDTO){
productService.update(productDTO);
return new ResponseEntity<>("Maxsulot ma'lumotlari yangilandi", HttpStatus.OK);
}
Now, I am surprized that, if I sent same data post method works fine(screen1), but put(screen2) method return validation error.
screen1(post)
screen2(put)
What the problem is?
MyDTO class:
public class ProductDTO {
private Long id;
private MultipartFile file;
#NotNull
#Size(min = 2, max = 50)
private String productName;
#NotNull
private Long productPrice;
private String productInfo;
#NotNull
private Long categoryId;
private String unitOfMeasurement;
// getters and setters
}
I can see you have #Validated that should validate your request body according to JSR-303.
Seems like it is not consistent when you POST and PUT. It validates/not validating and return an error because your body does not match the validation rules you placed on ProductDTO.
In all the docs I saw you should do something like #Valid #RequestBody instead of just putting #Validated.
Try to change it to the above and see if it now work more consistently.

Resources