org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver : Resolved - spring-boot

#Value("${mobileapi}")
private String mobileapi;
#Override
public String getcircleoperator(String mobilenum)throws JsonMappingException, JsonProcessingException {
HttpHeaders headers1 = new HttpHeaders();
HttpEntity<HttpHeaders> request = new HttpEntity<>(headers1);
RestTemplate restTemplate = new RestTemplate();
String newapivar=mobileapi+mobilenum.;
ResponseEntity<String> responsee = restTemplate.exchange(newapivar,HttpMethod.GET,request,String.class);
System.out.println("check these values new url"+responsee.getBody());
ObjectMapper mapper = new ObjectMapper();
MobileNumberResponse browsePlanResponses=mapper.readValue(responsee.getBody(), MobileNumberResponse.class);
return null;
}
I was try this code i get the error. in object mapper line throwing the Error. I don't know the why its just happened. can you please help me to solve this issues.

Related

How to pass multipart request parameter in rest template spring boot?

I have following controller code in one microservice :
#PostMapping("/posts/{postId}/images")
#RolesAllowed({Roles.USER, Roles.ADMIN})
public ResponseEntity<UploadImageResponse> uploadFile(#RequestParam("image") MultipartFile file, #AuthenticationPrincipal String username, #PathVariable(name = "postId") String postId) {
ImageMetadataEntity metadata = imageService.upload(file, username, postId);
UploadImageResponse uploadImageResponse = new UploadImageResponse(metadata.getFilename(), metadata.getUri(), metadata.getFileType(), metadata.getPostId());
return new ResponseEntity<>(uploadImageResponse, HttpStatus.CREATED);
}
I am calling this API from other microservice using rest template like below:
#Override
public UploadImageResponse uploadFile(UploadImageRequest request) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add(HttpHeaders.AUTHORIZATION, Constants.BEARER + " " + TokenContext.get());
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("image", request.getFile().getBytes());
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<UploadImageResponse> response = restTemplate
.postForEntity(String.format(IMAGE_UPLOAD_URL, MEDIA_SERVICE_HOST, request.getPostId()), requestEntity, UploadImageResponse.class);
return response.getBody();
}
But somehow this is not working. I am getting the below error :
2022-11-27 18:52:56.829 WARN 11120 --- [nio-8000-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'image' is not present]
But in when debugged HttpServletRequest.multipartParameterNames has the 'image' field i am sending.
Can someone tell me what is wrong ?
The issue is that the file is sent in request as request.getFile().getBytes(). When request comes to controller, spring checks for the file name and if its present then its added in multiPartFiles else they will be added in multiPartParameterNames in HttpServletRequest. When sent as getBytes(), the file name is null. I have fixed it by adding the below class
public class MultipartInputStreamFileResource extends InputStreamResource {
private final String filename;
public MultipartInputStreamFileResource(InputStream inputStream, String filename) {
super(inputStream);
this.filename = filename;
}
#Override
public String getFilename() {
return this.filename;
}
#Override
public long contentLength() throws IOException {
return -1;
}
}
and the request now is changed as this :
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("image", new MultipartInputStreamFileResource(request.getFile().getInputStream(), request.getFile().getOriginalFilename()));

How fix the issue of Compressed size after uploading the file in Imagekit.io site through the Spring boot rest Template

Controller
#PostMapping("/uploadimage")
public String uploadImage(#RequestParam("file") MultipartFile file) throws IOException {
return uploadSingleImageService.uploadSingleImage(file);
}
Service class
private final RestTemplate restTemplate;
Image img;
#Autowired
public UploadSingleImageServiceImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
#Override
public String uploadSingleImage(MultipartFile file) throws IOException {
ResponseEntity<String> urlResponse = null;
for (int i = 0; i < 2; i++) {
File originalFileName = new File(file.getOriginalFilename());
originalFileName.createNewFile();
FileOutputStream fos = new FileOutputStream(originalFileName);
fos.write(file.getBytes());
System.out.println(file.getSize());
fos.close();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", UrlConstant.auth);
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", originalFileName);
map.add("fileName", file.getOriginalFilename());
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
map, httpHeaders);
urlResponse = restTemplate.exchange(UrlConstant.uploadfileData, HttpMethod.POST, requestEntity,
String.class);
System.out.println(urlResponse.getStatusCode());
}
return urlResponse.getBody();
urlConstant
public static final String uploadfileData= "https://upload.imagekit.io/api/v1/files/upload";
Real fileSize = 686 KB
upload filesize = 23B
PostMan
Postman picture

Spring Boot RestTemplate: Bad request when directly copying from postman

So I have an API request where I am copying the details directly from postman where it works. I am however getting a bad request error.
#Service
public class GraphApiService {
#Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
#Autowired
RestTemplate restTemplate;
#Autowired
Constants constants;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public ResponseEntity<String> getAccessTokenUsingRefreshToken(Credential cred) throws IOException{
try {
//https://learn.microsoft.com/en-us/graph/auth-v2-user
// section 5. Use the refresh token to get a new access token
String url = "url";
JSONObject body = new JSONObject();
body.put("grant_type", "refresh_token");
body.put("client_id", "clientid");
body.put("scope","User.Read offline_access Files.Read Mail.Read Sites.Read.All");
body.put("redirect_uri", "http://localhost");
body.put("client_secret","secret");
body.put("refresh_token", "token");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<String> request = new HttpEntity<String>(body.toString(), headers);
ResponseEntity<String> response= restTemplate.postForEntity(url, request,String.class);
return response;
}
catch(HttpClientErrorException e){
logger.error(e.getResponseBodyAsString());
logger.error(e.getMessage());
return null;
}
}
I would appreciate any help. The bad request error message from microsoft graph isn't a descriptive one that will help
You're sending JSON payload with FORM_URLENCODED header.
Either you need to check if API accepts json payload, if so you need to change content-type to application/json or you can post form data as follows.
public ResponseEntity<String> getAccessTokenUsingRefreshToken(Credential cred) throws IOException{
try {
//https://learn.microsoft.com/en-us/graph/auth-v2-user
// section 5. Use the refresh token to get a new access token
String url = "url";
MultiValueMap<String, String> multiValueMap= new LinkedMultiValueMap<String, String>();
multiValueMap.add("grant_type", "refresh_token");
multiValueMap.add("client_id", "clientid");
//.....
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(multiValueMap, headers);
ResponseEntity<String> response= restTemplate.postForEntity(url, request, String.class);
return response;
}catch(HttpClientErrorException e){
logger.error(e.getResponseBodyAsString());
logger.error(e.getMessage());
return null;
}
}

Spring-boot Resttemplate response.body is null while interceptor clearly shows body

With Spring-boot 1.5.10.RELEASE, I am getting response.body as null.
Here is how I am using RestTemplate
RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LoggingRequestInterceptor());
restTemplate.setInterceptors(interceptors);
String url = "http://someurl/Commands";
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("cmd", "{\"operation\":\"getSomeDetails\"}}");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
System.out.println("This is always null: " + response.getBody());
While above program always prints null,
following interceptor prints valid response body
public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);
#Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
traceRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
traceResponse(response);
return response;
}
private void traceResponse(ClientHttpResponse response) throws IOException {
StringBuilder inputStringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
String line = bufferedReader.readLine();
while (line != null) {
inputStringBuilder.append(line);
inputStringBuilder.append('\n');
line = bufferedReader.readLine();
}
log.debug("============================response begin==========================================");
log.debug("Status code : {}", response.getStatusCode());
log.debug("Status text : {}", response.getStatusText());
log.debug("Headers : {}", response.getHeaders());
log.debug("Response body: {}", inputStringBuilder.toString());
log.debug("=======================response end=================================================");
}
}
Although the accepted answer has the reason, I believe the solution is also necessary.
Spring has a BufferingClientHttpRequestFactory that acts as a wrapper to Rest Template's default SimpleClientHttpRequestFactory.
It can be passed to a Rest Template during creation. This forces the Rest Template to make interceptors use a copy of the response rather than destroying it.
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
RestTemplate restTemplate = new RestTemplate(factory);
Source :
http://objectpartners.com/2018/03/01/log-your-resttemplate-request-and-response-without-destroying-the-body/
You're consuming the response body in traceResponse; that's your problem. Also, please update your question to be specific; "all latest" means nothing. What's latest today isn't so tomorrow.
Below code will resolve issue.
#Bean public RestTemplate restTemplate() {
final RestTemplate restTempate = new RestTemplate(new BufferingClientHttpRequestFactory(new
SimpleClientHttpRequestFactory()));
final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LogHttpInterceptor());
restTempate.setInterceptors(interceptors);
return restTemplate;}
While log interceptor will be like below
public class LogHttpInterceptor implements ClientHttpRequestInterceptor {
final static Logger log = LoggerFactory.getLogger(LogHttpInterceptor.class);
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
traceRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
traceResponse(response);
return response;
}
private void traceRequest(HttpRequest request, byte[] body) throws IOException {
log.info("===========================================================================request begin");
log.debug("URI : {}", request.getURI());
log.debug("Method : {}", request.getMethod());
log.debug("Headers : {}", request.getHeaders() );
log.debug("Request body: {}", new String(body, "UTF-8"));
log.info("=============================================================================request end");
}
private void traceResponse(ClientHttpResponse response) throws IOException {
StringBuilder inputStringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
String line = bufferedReader.readLine();
while (line != null) {
inputStringBuilder.append(line);
inputStringBuilder.append('\n');
line = bufferedReader.readLine();
}
log.info("==========================================================================response begin");
log.debug("Status code : {}", response.getStatusCode());
log.debug("Status text : {}", response.getStatusText());
log.debug("Headers : {}", response.getHeaders());
log.debug("Response body: {}", inputStringBuilder.toString());
log.info("===========================================================================response end");
}
Let me know if doesn't work
After some time of searching I tried to use HttpComponentsClientHttpRequestFactory() instead of SimpleClientHttpRequestFactory()
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory());
That solved the issue for me.
Create your RestTemplate like this
#Bean
public RestTemplate interceptedRestTemplate() {
RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory()
));
restTemplate.setInterceptors(List.of(<i>your interceptor</i>));
return restTemplate;
}
worked for me.

How to request POST using RestTemplate, authorized using user password

Can some one tell how I can use RestTemplate to POST a HttpEntity object using Authorization. I am using below code in test application
Client Side :
public class FifthWay extends Thread {
public void run() {
String plainCreds = "anuj:khare";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<String> postRequest = new HttpEntity<String>("FifthWay",headers);
RestTemplate rt = new RestTemplate();
rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
rt.getMessageConverters().add(new StringHttpMessageConverter());
String postUri = new String("http://169.194.48.182:8080/trade-capture-service/deals/persist");
ResponseEntity<String> responseForPost = rt.exchange(postUri,HttpMethod.POST, postRequest, String.class);
String responseStringForPost = responseForPost.getBody();
System.out.println(responseStringForPost);
}
}
Server side :
#Controller
#RequestMapping("/deals")
public class RestController {
...
...
#RequestMapping(value = "/check", method = RequestMethod.GET)
public #ResponseBody
String justACheck() {
System.out.println("It Works");
return "It works";
}
Getting errors like :
Exception in thread "Thread-4" org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
OR
Exception in thread "Thread-4" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
Please help
Here is the example of RestTemplate exchange :
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
final HttpEntity entity = new HttpEntity(restCanvas, requestHeaders);
return restTemplate.exchange(canvasAddUrl + value, HttpMethod.POST, entity, Integer.class);
Here canvasAddURL is the URL you wish to call with context-path. If you want to add a cookie to it, lemme know, i have removed that code as it is most of the time not necessary. The return value for this is ResponseEntity<Integer> . Check it out.

Resources