ReactJS API request failing - reactjs

I am developing a react app using Spring Boot backend.
I am not very friendly with Java or Spring Boot and now I am stuck with an issue.
Bellow is backend method code which is handling the request
#RestController
#RequestMapping("/toys")
public class ToysController {
#Autowired
private ToysService toysService;
#CrossOrigin(origins = "*")
#PostMapping("/addtoy")
public ResponseEntity<Toys> addToy(#RequestParam("file") MultipartFile file,
#RequestParam("toyName") String toyName,
#RequestParam("toyDescription") String toyDescription,
#RequestParam("toyPrice") Long toyPrice,
#RequestParam("quantity") int quantity,
#RequestParam("availability") Boolean availability,
#RequestParam("sellerId") Long sellerId) throws IOException{
Toys toy = new Toys();
toy.setToyName(toyName);
toy.setToyDescription(toyDescription);
toy.setQuantity(quantity);
toy.setToyPrice(toyPrice);
toy.setAvailability(availability);
toy.setSellerId(sellerId);
toy.setToyImage(ImageEncoderDecoder.compressBytes(file.getBytes()));
toy.setImageName(file.getOriginalFilename());
Toys toyRes = toysService.addToy(toy);
if(toyRes!=null) {
toyRes.setToyImage(ImageEncoderDecoder.decompressBytes(toyRes.getToyImage()));
return new ResponseEntity<Toys>(toyRes,HttpStatus.OK);
}
else {
return new ResponseEntity<Toys>(HttpStatus.NO_CONTENT);
}
}
}
Below are the request details I am supposed to use
API: http://localhost:8081/toys/addtoy
Method: POST
Body:
[{"key":"toyName","value":"Car","type":"text","enabled":true},
{"key":"toyDescription","value":"small car 6 month old","type":"text","enabled":true},
{"key":"toyPrice","value":"600","type":"text","enabled":true},
{"key":"quantity","value":"2","type":"text","enabled":true},
{"key":"availability","value":"true","type":"text","enabled":true},
{"key":"file","type":"file","enabled":true,"value":[]},
{"key":"sellerId","value":"1","type":"text","enabled":true}]
Response: Status code 200
Following is how I am trying to hit the API
export const addToy = toy => {
const requestOptions = {
mode: 'cors',
method: 'POST',
headers: {
"Content-Type": "multipart/form-data; boundary=%%",
'Access-Control-Allow-Origin' : '*'
},
body: toy
};
fetch(`${API}/toys/addtoy`, requestOptions) // API = 'http://localhost:8081'
.then(response => {
if(response.status === 200)
console.log('Toy Inserted');
console.log('Resopose : ', response);
})
.catch(err => {
console.log('Error while inserting toy : ', err);
})
}
Calling the above method
const handleSubmit = e => {
e.preventDefault()
let formData = new FormData()
formData.append('toyName', toyName)
formData.append('toyDescription', toyDesc)
formData.append('toyPrice', parseInt(toyPrice))
formData.append('quantity', parseInt(toyQty))
formData.append('availability', parseInt(toyQty) > 0)
formData.append('file', image)
formData.append('sellerId', parseInt(loggedIn.loggedInUser.userId))
addToy(formData)
}
The response I am getting back
body: ReadableStream
locked: false
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 400
statusText: ""
type: "cors"
url: "http://localhost:8081/toys/addtoy"

Related

How to share image between Spring-Boot and React

I am developing full stack internet-market and i need to send image to my Spring Rest Controller and save it to db. How to do that? I tryed something like that:
setFile(e.target.files && e.target.files[0])
This file is file from <input type="file"/>
After that i send this file to my put method
DishesService.addDish(dish, file)
static async addDish(dish: IDish, file: any) {
try {
await axios.post<IDish>('http://localhost:8080/dishes', dish)
.then(response => {
this.updateDishImage(response.data.id, file)
})
} catch (e) {
console.log('произошла ошибка при добавлении блюда')
}
}
static async updateDishImage(id: number | undefined, image: any) {
try {
await axios.put('http://localhost:8080/dishes/' + id, {}, {
params: {
file: image
}
})
} catch (e) {
console.log('Произошла ошибка при добавлении картинки к блюду')
}
}
And my Spring Boot Put method:
#PutMapping("{dishId}")
public ResponseEntity<DishEntity> updateDishImage(#PathVariable Long dishId, #RequestParam("file") MultipartFile file) {
DishEntity updateDish = dishService.updateDishImage(file, dishId);
return ResponseEntity.ok(updateDish);
}
I get exception:
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
You are missing the headers:
headers: {
"Content-Type": "multipart/form-data",
}
in your axios call
Try this :
#RequestMapping(path = "{dishId}", method = PUT, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
public ResponseEntity<DishEntity> updateDishImage(#PathVariable Long dishId, #RequestPart("file") MultipartFile file) {
// your logic
}
You can also encode you images into base64, then send them to the server-side as string.

Cookie not set in chrome even when React app is served from the same port as Spring Boot

I have an application running on http://localhost:8181/ which has React integrated with Spring Boot. (both run on the same port).
I send this POST request to http://localhost:8181/public/authenticate using axios:
The axios instance:
export const axios_register_login_user = axios.create({
baseURL: '/public',
withCredentials: true,
headers: { "content-type": "application/json" },
method: 'POST'
})
The login request:
export async function login(username, password, callback) {
axios_register_login_user.post("/authenticate", {
'username': username,
'password': password
}).then(response => {
console.log("success", response);
callback(response.data);
}).catch(error => {
console.log("failed", error);
callback("Failed");
})
}
The login is successful and I can see a cookie being returned in the response
However, this cookie is not set in the Application->Cookies tab
Here's my API code:
#RequestMapping(value = "/authenticate", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<?> authenticateUser(#RequestBody AuthenticationRequest request, HttpServletResponse response) {
try {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword());
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
} catch (BadCredentialsException e) {
throw new BadCredentialsException("Invalid details");
}
UserDetailsImpl userDetails = (UserDetailsImpl) userDetailsService.loadUserByUsername(request.getUsername());
String name = userDetails.getUser().getName();
String generatedToken = jwtUtil.generateToken(userDetails);
Cookie cookie = new Cookie("jwt", generatedToken);
cookie.setMaxAge(60 * 60 * 10);//like JWT, the max age is 10 hours
// cookie.setSecure(false);
cookie.setHttpOnly(true);
response.addCookie(cookie);
return new ResponseEntity<>(new AuthenticationResponse(name + " " + generatedToken), HttpStatus.OK);
}
I tried adding
#CrossOrigin(allowCredentials = "true", origins = "{http://localhost:3000,http://localhost:8181}")
to the above method but it didn't help.
Please help me out with this. I've been stuck here for 2 days now :(
I was missing cookie.setPath("/") in my code.
Additionally, I also did cookie.setSecure(false);
After these changes, the cookie was added to the browser

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported

``#PostMapping(value = "/staff/saveStaff" , consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public String saveStaff(#RequestPart("staff") Staff staff,#RequestPart("profilePic") MultipartFile profilePic) {
logger.debug(" Staff "+staff+":"+profilePic);
return null;
}`
Want to post Json object and MultipartFile in one request, tried #ModelAttribute instead of #RequestPart so received file object, but Staff object is null.
Tried to change Media type but did not worked, removed media type still not working,
Http request in React js: using Axios
var formData = new FormData();
formData.append("profilePic",this.state.profilePic)
formData.append("staff",{...this.state.staff})
axios.post("/staff/saveStaff",
formData,
{headers: {
'Content-Type': 'multipart/form-data'
}}
)
.then(res => {
if (res.status === 200) {
console.log("Saved");
}
})

View pdf from spring get request via react/axios

I have a spring endpoint that serves a pdf as a byte[] and a React ui that is getting a 406 when I try to call the endpoint.
spring endpoint:
#GetMapping(value = "report/{report_id}", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> generateReviewTaskReport(
HttpServletResponse response,
#PathVariable("report_id") String reportId,
#RequestAttribute(USER_ID) String loginId) {
byte[] report = reportService.generateReport(reportId, loginId);
ByteArrayInputStream inputStream = new ByteArrayInputStream(report);
HttpHeaders headers = new HttpHeaders();
headers.setContentLength(report.length);
headers.add("Content-Disposition", "inline;filename=" + reportId + "_report.pdf");
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(inputStream));
}
I've tried:
headers.add("Content-Disposition", "attachment;filename=" + reportId + "_report.pdf");
same result.
react request:
export const getReport = (reportId = '') => (dispatch) => {
const report = `${apiConfig.reportUrl}${reportId}`
const promise = axios.get(report,
{
responseType: 'blob',
headers: {
'Accept': 'application/pdf'
}
})
return dispatch({
type: GET_REPORT,
payload: promise,
})
}
case GET_REPORT:
if (payload.data) {
const report = new Blob([payload.data])
reportUrl = URL.createObjectURL(report)
window.open(reportUrl, "_blank")
}
I've tried responseType: 'bufferArray', returning a plain byte[] from my spring endpoint, always get a 406. I'm guessing it's because I have the wrong mime type in my 'Accept' header. I've tried 'application/pdf' and '*/*', same result. What headers do I need to accept an InputStreamResource or byte[]?
With postman I can download the file just fine.
my config:
#Component
public class WebConfiguration extends WebMvcConfigurationSupport {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(byteArrayHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter());
}
#Bean
public HttpMessageConverter byteArrayHttpMessageConverter() {
ByteArrayHttpMessageConverter arrayHttpMessageConverter =
new ByteArrayHttpMessageConverter();
arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
return arrayHttpMessageConverter;
}
private List<MediaType> getSupportedMediaTypes() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_PDF);
mediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
return mediaTypes;
}
}
A general solution, but i think in you'r case it should works fine ;)
axios({
url: 'http://api.dev/file-download', //your url
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf'); //or any other extension
document.body.appendChild(link);
link.click();
});
gist: https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
Full credits to: https://gist.github.com/javilobo8

ionic 3 acces to json key

i can't access to a key of a json response from a restful web service.
{"_body":"{\"values\": {\"user_id\":\"1\",\"name\":\"fred test\",\"email\":\"fred#test.test\",\"username\":\"fredtest\",\"token\":\"d5f66a06ec809d70d0c52842df8dc0011d7d1ad0f2d56f50d3123da17a2489fe\"}}","status":200,"ok":true,"statusText":"OK","headers":{"pragma":["no-cache"],"content-type":["text/html;charset=UTF-8"],"cache-control":["no-store"," no-cache"," must-revalidate"],"expires":["Thu"," 19 Nov 1981 08:52:00 GMT"]},"type":2,"url":"http://localhost/PHP-Slim-Restful/api/login"}
I would like to acces to 'values' in this function: (this.responseData.values)
login(){
console.log('login'+ this.userData);
// Your app login API web service call triggers
this.authService.postData(this.userData,'login').then((result) => {
this.responseData = result;
console.log('userdata : '+ temp);
if(this.responseData.values){
console.log('response: ' + this.responseData);
localStorage.setItem('userData', JSON.stringify(this.responseData));
this.navCtrl.push(TabsPage);
}
else{
this.showToastWithCloseButton()
}
}, (err) => {
console.log('erreur : '+err);
});
}
I have an error undifined!
Can you help me?
I have used Observable to return json data and using the subscribe function in my method and using response.json() to convert the JSON reponse from RESTful webservices.
My component method,
import {Http, Headers, Response, RequestOptions} from '#angular/http';
import {Observable} from 'rxjs/Rx';
var response = this.service.post('deleteUserDetails/'+this.selectedUserId, null);
response.subscribe((res) => {
var response = res.json();
});
Service Post method,
post(url: string, data : any): Observable<any> {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers});
return this.http.post(url, data,{headers: headers});
}
I think this might be helpful for your query.
You can make a for in your JSON and access the return values of your post. Something like that.
"this.responseData = result.json();" -> Return JSON. Make a for.
Example:
public postData(data, url: string) {
this.http.post(url, data).toPromise().then(res => {
let responseData = res.json();
if (responseData) {
for (var item of responseData) {
//Implments
}
}
}, (err) => {
});
}

Resources