SpringBoot simple multipart file upload with Advanced rest client (Chrome) - spring

I want to upload a image to the file system. So I am using Multi-part file upload with spring boot. And also I am using Advance Rest Client(Chrome) tool to POST Multi part file. But I am facing an error even I do not specify any content type org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found.
Here my rest controller code,
#RestController
public class StringController {
#RequestMapping(value="/upload", method=RequestMethod.POST)
public #ResponseBody String singleSave(#RequestParam("file") MultipartFile file){
String fileName = null;
if (!file.isEmpty()) {
try {
fileName = file.getOriginalFilename();
byte[] bytes = file.getBytes();
BufferedOutputStream buffStream =
new BufferedOutputStream(new FileOutputStream(new File("F:/" + fileName)));
buffStream.write(bytes);
buffStream.close();
return "You have successfully uploaded " + fileName;
} catch (Exception e) {
return "You failed to upload " + fileName + ": " + e.getMessage();
}
} else {
return "Unable to upload. File is empty.";
}
}
}
Screenshot (Advance rest client tool)
Error
{
"timestamp": 1490678908517,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.web.multipart.MultipartException",
"message": "Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found",
"path": "/upload"
}

The problem is in your request from advance rest client. It is working fine in the postman.The image is getting uploaded. Try with postman you will get it.

You lost in you client request headers value boundary.
Construct in PostMan header "Content-Type" like this:
Content-Type : multipart/form-data;boundary="12312313132132"

Related

application/json not supported when passing multipart files and json together

I have a REST controller method which will take multipart files and JSON object to save as a product with images.
Here is my controller method.
#PostMapping(value = "/{username}/saveProduct", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE})
public void saveProduct(#PathVariable("username") String username,
#RequestPart("multipartFiles") List<MultipartFile> multipartFiles,
#RequestPart("product") Product product)
{
Users user = userService.findUserByUsername(username);
List<Images> listOfImages = productService.getBLOBfromFile(multipartFiles, product);
product.setImages(listOfImages);
product.setUser(user);
user.setProducts(product);
userService.saveUser(user);
}
For some reason I am getting this error:
"timestamp": "2021-01-18T20:05:32.409+00:00",
"status": 415,
"error": "Unsupported Media Type",
"trace": "org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported\r\n\tat org.
From postman I am sending
I tried using #RequestParam and #ModelAttribute as well. Did not work for me.
Also, this method was working when I was writing MVC app.

How to refresh access_token on server side(JAVA)?

I am using a spring boot as my backend application.
I have stored our client's access_token, refresh_token, and access_id in my postgresql database.
Here is my code trying to get the new access token if token expired.
public void refreshGoogleIdToken(GoogleAuthEntity googleAuthEntity) {
LOGGER.debug("GoogleAuthService.refreshGoogleIdToken()");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(transport)
.setJsonFactory(jsonFactory)
.setClientSecrets(googleAuthClientId, googleAuthClientSecret)
.build();
credential.setAccessToken(googleAuthEntity.getAccessToken());
credential.setRefreshToken(googleAuthEntity.getRefreshToken());
try {
if (credential.refreshToken()) {
Long newExpireTime = credential.getExpirationTimeMilliseconds();
String newAccessToken = credential.getAccessToken();
String newRefreshToken = credential.getRefreshToken();
LOGGER.debug("NewAccessToken: " + newAccessToken);
LOGGER.debug("NewRefreshToken: " + newRefreshToken);
LOGGER.debug("NewExpireTime: " + newExpireTime);
}
} catch (IOException e) {
LOGGER.debug("GoogleAuthService.refreshGoogleIdToken() - IOException");
e.printStackTrace();
}
}
Google return 400 error, and the description is: 400 Bad Request
{
"error" : "invalid_grant",
"error_description" : "Bad Request"
}
What mistake that I have make?
Thanks
I have been using OAuth2 with spring framework and have only encountered this error "Invalid grant" in case if refresh token is invalid, expired, revoked or does not match the redirection uri used in the authorization request, or is issued to another client
For your situation I think you should delete the stored refresh token / rectify it and debug your code again. This may be due to wrong token info stored in your PostgreSQL database while testing.

Subscribing to Angular 6 POST request

Scenario
I have an Angular 6 front end that communicates with a Spring Boot back end. The back end uses PostgreSQL as a database. The thing I want to do is to send a username to the data base and then return his email and print it on a page using Angular 6.
But, I am struggling with the Angular POST request where on subscribing to it I get a JSON parsing error in Chrome developer tools.
Code
Spring Boot
This works fine as I have tested it by printing the email returned from the database on the console.
#RequestMapping(value = "/reset", method = RequestMethod.POST)
public String resetMail(#RequestBody String username) {
try{
User user = userService.findByUsername(username);
//System.out.println(user.getEmail()); Testing purpose
return user.getEmail();
}catch(Exception e) {
//e.printStackTrace(); Prints out NullException StackTrace.
return "Not Present";
}
}
Angular 6
In the following code, I think the problem is in the subscription method as I am getting a JSON parsing error in Chrome developer tools.
httpOptions = { headers: new HttpHeaders({'Content-Type':'text/plain', 'Access-Control-Allow-Origin': '*'})};
reset(username:string) {
this.http.post('http://localhost:8090/reset', username, this.httpOptions).subscribe(data=> {
this.email = data as any;
});
}
console.log(this.email) // Prints undefined
Error
HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:8090/reset", ok: false, …}
>error: {error: SyntaxError: Unexpected token a in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttp…, text: "abcdefg#yahoo.com"}
>headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure during parsing for http://localhost:8090/reset"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:8090/reset"
You want to serialize a string to JSON. If your controller would return an object the #RestController annotation would serialize it properly. In case you want to return just a string you have to return JSONObject.quote(user.getEmail()); You can get the JSONObject dependency from here http://mvnrepository.com/artifact/org.json/json
But I encourage you to always return objects as a response from your rest controllers.

Calling Web API method in postman

I am trying to call the following Web API method in Postman:
public HttpResponseMessage GetAllNotifications(HttpRequestMessage request, String Name)
{
HttpResponseMessage response = null;
try
{
List<ExpandoObject> res = _userProcess.GetAllNotifications(Name);
response = request.CreateResponse<List<ExpandoObject>>(HttpStatusCode.OK, res);
}
catch (Exception ex)
{
response = request.CreateResponse<string>(HttpStatusCode.BadRequest, "Unable to process your request Please contact administration");
throw new DataException(ex.Message.ToString());
}
return response;
}
Any advice appreciated.
Just run your Project in localhost and copy the Url from the Browser and add
your Api name , Example if the Project runs with an url like : https://localhost:3000/api/values
Just change the url with your api name in place of "values"
https://localhost:3000/api/GetAllNotifications and now paste this url in postman and set get method and click on send make sure your project is running in the same localhost port Number.

Unsupported Media Type in postman

I am implementing spring security with oauth2 and jwt.
the below is my login function
function doLogin(loginData) {
$.ajax({
url : back+"/auth/secret",
type : "POST",
data : JSON.stringify(loginData),
contentType : "application/json; charset=utf-8",
dataType : "json",
async : false,
success : function(data, textStatus, jqXHR) {
setJwtToken(data.token);
},
error : function(jqXHR, textStatus, errorThrown) {
alert("an unexpected error occured: " + errorThrown);
window.location.href= back+'/login_page.html';
}
});
}
And down I have the Controller
#RequestMapping(value = "auth/secret", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(#RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException {
System.out.println();
logger.info("authentication request : " + authenticationRequest.getUsername() + " " + authenticationRequest.getPassword());
// Perform the security
System.out.println( authenticationRequest.getUsername()+"is the username and "+authenticationRequest.getPassword());
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
authenticationRequest.getUsername(),
authenticationRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
logger.info("authentication passed");
// Reload password post-security so we can generate token
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails, device);
logger.info("token " + token);
// Return the token
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
But when I try the post request with the postman it shows me
{
"timestamp": 1488973010828,
"status": 415,
"error": "Unsupported Media Type",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
"message": "Content type 'multipart/form-data;boundary=----WebKitFormBoundaryY4KgeeQ9ONtKpvkQ;charset=UTF-8' not supported",
"path": "/TaxiVis/auth/secret"
}
But when I do cosole.log(data) in the ajax call it prints the token?I could not figure out what is wrong.Any help is appreciated.
You need to set the content-type in postman as JSON (application/json).
Go to the body inside your POST request, there you will find the raw option.
Right next to it, there will be a drop down, select JSON (application.json).
Http 415 Media Unsupported is responded back only when the content type header you are providing is not supported by the application.
With POSTMAN, the Content-type header you are sending is Content type 'multipart/form-data not application/json. While in the ajax code you are setting it correctly to application/json. Pass the correct Content-type header in POSTMAN and it will work.
I also got this error .I was using Text inside body after changing to XML(text/xml) , got result as expected.
If your request is XML Request use XML(text/xml).
If your request is JSON Request use JSON(application/json)
If you are still failing with Unsupported Media Type in postman
when calling a SOAP endpoint you could try:
Content-Type: application/soap+xml
i was also having a similar issue. in my case i made two changes
Click on headers tag and add a key 'Content-Type' with Value 'application/json'
Second step is to click on Body tab and select 'raw' radio button and select type as 'JSON' from dropdown as shown below
I had this problem. I had authentication on the authentication tab set up to pass credentials in body.
This error occurred for me when I had the Body set to None.
So I needed an empty body in postman, set to raw JSON to allow this to work even though my main request was parameters in the querystring.
{
}
When this was happening with me in XML;
I just changed "application/XML" to be "text/XML",
which solved my problem.

Resources