Spring Boot - Request method 'POST' not supported to upload file - java

Front: Angular2+
Back: Java15 Spring Boot
DataBase: MySql
I take all examples for upload files in database form in byte[]. with a complex object with file by attribute.
I try desperately to upload an image file on my database so I try to create post API rest by I have error
I'm take
o.s.web.servlet.PageNotFound : Request method 'POST' not supported
#PostMapping(value = "/Ninja/image/")
public ResponseEntity<ResponseMessage> saveNinjaImage(#RequestParam("file") MultipartFile file) {
String message = "";
try {
Iterable<Syndic> lstN= NinjaRepository.findAll();
if(lstN.iterator().hasNext()) {
Ninja s = lstN.iterator().next();
s.setPicture(file.getBytes());
logger.info(s.toString());
}
} catch(Exception e) {
//return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
logger.info(e.toString());
}
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
}
//service
public postNinja(file: File) {
const formData: FormData = new FormData();
formData.append('file', file);
const req = new HttpRequest('POST', `${this.host}/Ninja/image`, formData, {
headers: this.headers,
reportProgress: true,
responseType: 'json'
});
return this.http.request(req);
}
/* ts */
public onSave() {
this.frontDynamic.submitted = true;
if (this.frontDynamic.updateNinja.invalid) {
return;
} else {
const formValue = this.frontDynamic.updateNinja.value;
const newNinja = new Ninja(formValue['nom']);
newNinja.address = formValue['adresse'];
newNinja.description = formValue['description'];
newNinja.website = formValue['site'];
this.ninjaService.putNinja(newNinja,formValue['image']).subscribe(response => {},
error => {console.log(error);}
,
()=>{
this.ninjaService.postNinja(formValue['image']).subscribe(
event => {},
err => {});
);
}
}

Related

A problem requesting base64 encoded file React - Spring Boot

I have a problem with sharing image between Spring and React. What i do:
I get file from input:
<input type='file' id='upload-button' accept='image/*'
onBlur={() => image.onBlur()}
onChange={e => onChangeHandler(e)}/>
Then my handlerMethod with base64Encoder:
const onChangeImage = async (e: any) => {
const file = e.target.files[0]
const base64 = await convertToBase64(file)
setValue(base64)
}
export const convertToBase64 = (file: any) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = () => {
resolve(fileReader.result)
}
fileReader.onerror = (error) => {
reject(error)
}
})
}
And after that i send this file to method:
DishesService.addDish(dish, image.value)
This method:
export default class DishesService {
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 controller:
#PutMapping(path = "{dishId}")
public ResponseEntity<DishEntity> updateDishImage(#PathVariable Long dishId, #RequestParam("file") String base64File) {
DishEntity updateDish = dishService.updateDishImage(base64File, dishId);
return ResponseEntity.ok(updateDish);
}
Method:
#Override
public DishEntity updateDishImage(String base64File, Long id) {
DishEntity dishById = findById(id);
byte[] byteImage = Base64.decodeBase64(base64File);
dishById.setImage(byteImage);
DishEntity updatedDish;
try {
updatedDish = dishRepository.save(dishById);
} catch (Exception ex) {
throw new OperationFailedException("Update dish image method failed!");
}
return updatedDish;
}
Whan i do my code, I get exception:
Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible value. Expected the discarded bits to be zero.
If you faced with this problem, please, help me to fix this error

How can I send an image in JPEG format from Java Spring Boot to Angular

Currently, I try to send an image file in JPEG format to Angular. However, I'm getting the following error when I send it out through Postman.
class
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile
cannot be cast to class java.lang.String
(org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile
is in unnamed module of loader 'app'; java.lang.String is in module
java.base of loader 'bootstrap')
The idea is to upload this image into cloudinary repository.
Here my code of the REST API:
#PostMapping("/uploads")
public ResponseEntity<?> upload(MultipartFile imagen) throws Exception {
Map<String, Object> response = new HashMap<>();
File conversion = new File(imagen.getOriginalFilename());
imagen.transferTo(conversion);
Cloudinary cloudinary = new Cloudinary();
cloudinary.uploader().upload("C:\\Users\\Dell\\Pictures\\"+conversion.getName(), ObjectUtils.asMap("public_id", imagen,
"api_key", "xxxxxxxxxxxxxxx", "api_secret", "xxxxxxxxxxxxxxxxxxxxxx", "cloud_name", "xxxxxxx"));
return new ResponseEntity<Map<String, Object>>(HttpStatus.CREATED);
}
Any Suggest will be appreciated
Code in Angular service Layer called paciente.services.ts
#Injectable({
providedIn: 'root'
})
export class PacienteService extends GenericService<Paciente> {
private pacienteCambio: Subject<Paciente[]> = new Subject<Paciente[]>
();
private mensajeCambio: Subject<string> = new Subject<string>();
constructor(protected http: HttpClient) {
super(
http,
`${environment.HOST}/pacientes/uploads`);
}
listarPacientes(){
return this.http.get<any>(`${this.url}`);
}
listarPageable(p: number, s:number){
return this.http.get<any>(`${this.url}/pageable?
page=${p}&size=${s}`);
}
subirImagen(archivo: string){
return this.http.post(`${this.url}/${archivo}`,archivo);
}
obtenerURLImagen(nombreImagen: String){
return this.http.get<Paciente[]>
(`${this.url}/descripcionAssets/${nombreImagen}`);
}
listar(){
return this.http.get<Paciente[]>(this.url);
}
listarPorId(id: number){
return this.http.get<Paciente>(`${this.url}/${id}`);
}
registrar(paciente: Paciente){
return this.http.post(this.url, paciente);
}
modificar(paciente: Paciente){
return this.http.put(this.url, paciente);
}
eliminar(id: number){
return this.http.delete(`${this.url}/${id}`);
}
//////////////////////////
getPacienteCambio(){
return this.pacienteCambio.asObservable();
}
setPacienteCambio(lista: Paciente[]){
this.pacienteCambio.next(lista);
}
getMensajeCambio(){
return this.mensajeCambio.asObservable();
}
setMensajeCambio(msj: string){
this.mensajeCambio.next(msj);
}
}
And this is the component where I setup the REST API subirImagen
export class PacienteEdicionComponent implements OnInit {
id: number = 0;
edicion: boolean = false;
nombreArchivo: File;
form: FormGroup;
public archivos: any = []
public files: NgxFileDropEntry[] = [];
constructor(
private route: ActivatedRoute,
private router: Router,
private pacienteService: PacienteService,
private sanitizer: DomSanitizer
) { }
ngOnInit(): void {
this.form = new FormGroup({
'id': new FormControl(0),
'nombres': new FormControl(''),
'apellidos': new FormControl(''),
'dni': new FormControl(''),
'telefono': new FormControl(''),
'direccion': new FormControl(''),
'fondo-imagen': new FormControl(''),
'email': new FormControl(''),
});
this.route.params.subscribe(data => {
this.id = data['id'];
this.edicion = data['id'] != null;
this.initForm();
});
}
for (const droppedFile of files) {
// Is it a file?
if (droppedFile.fileEntry.isFile) {
const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
fileEntry.file((file: File) => {
// Here you can access the real file
this.nombreArchivo = file;
**//This is the test i make to find out if image is uploaded**
this.pacienteService.subirImagen(**this.nombreArchivo.name**);
// You could upload it like this:
const formData = new FormData()
formData.append('logo', file)
// Headers
/* const headers = new HttpHeaders({
'security-token': 'mytoken'
})
this.http.post('https://mybackend.com/api/upload/sanitize-and-save-
logo', formData, { headers: headers, responseType: 'blob' })
.subscribe(data => {
// Sanitized logo returned from backend
})
**/
});
} else {
// It was a directory (empty directories are added, otherwise only
files)
const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
console.log(droppedFile.relativePath, fileEntry);
}
}
}
#PostMapping(value="/uploads", consumes = {
MediaType.MULTIPART_FORM_DATA_VALUE })
public ResponseEntity<?> guardarImagen(#RequestParam("adjunto")
MultipartFile file, Integer id) throws Exception{
Paciente pac = service.listarPorId(id);
//Se valida si existe el id en la base de datos
if(pac == null) {
throw new ModeloNotFoundException("ID NO ENCONTRADO " + id);
}
String fotoUsuario = file.getOriginalFilename();
Cloudinary cloudinary = new Cloudinary();
cloudinary.uploader().upload(file.getBytes(),
ObjectUtils.asMap("public_id", file.getOriginalFilename()));
Map result = cloudinary.api().resource(file.getOriginalFilename(),
ObjectUtils.emptyMap());
service.actualizarFoto(id, fotoUsuario);
return new ResponseEntity<>(result, HttpStatus.OK);
}

CKEditor 5 upload image, What information does the upload image return?

This is web code:
DecoupledEditor
.create( document.querySelector( '#webDetails' ),{
language: 'zh-cn',
image: {
toolbar: [ 'imageTextAlternative' ],
styles: [ 'full', 'side' ]
},
ckfinder: {
uploadUrl: '<%=WEBPATH%>/platform/updateMaterial'
}
} )
.then( editor => {
const toolbarContainer = document.querySelector( '#toolbar-webDetails' );
toolbarContainer.appendChild( editor.ui.view.toolbar.element );
} )
This is Spring controller:
#PostMapping("updateMaterial")
#ResponseBody
public String updateMaterial(#RequestParam("upload") MultipartFile file, HttpServletRequest request){
String trueFileName = null;
String realPath = null;
try {
realPath = request.getSession().getServletContext().getRealPath("/upload");
System.out.println(realPath);
trueFileName = uploadImg(realPath, file);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return "{\"default\":\"" + realPath + File.separator + trueFileName + "\"}";
}
Here I return the address of the image on disk.
It is json String style. I want CKEditor 5 api to return the information, but still failure.
What do I need to return in the background to succeed, or am I missing the step?
thank you.
There are many people asking this question, but none of them have a clear solution. Finally, I found it. My code is as follows.
class UploadAdapter {
constructor(loader) {
this.loader = loader;
}
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('upload', this.loader.file);
data.append('allowSize', 10);//允许图片上传的大小/兆
$.ajax({
url: 'loadImage',
type: 'POST',
data: data,
dataType: 'json',
processData: false,
contentType: false,
success: function (data) {
if (data.res) {
resolve({
default: data.url
});
} else {
reject(data.msg);
}
}
});
});
}
abort() {
}
}
DecoupledEditor
.create( document.querySelector( '#b' ), {
language:"zh-cn"
})
.then( editor => {
const toolbarContainer = document.querySelector( '#a' );
toolbarContainer.appendChild( editor.ui.view.toolbar.element );
// This place loads the adapter.
editor.plugins.get('FileRepository').createUploadAdapter = (loader)=>{
return new UploadAdapter(loader);
};
} )
.catch( error => {
console.error( error );
} );

Angular js file upload to server via REST call

data passed in uploadData function contains below value:
lastModified:1478845421494
lastModifiedDate:Fri Nov 11 2016 11:53:41 GMT+0530 (India Standard Time)
name:"u_ex150626.log"
size:2022067
type:""
webkitRelativePath:""
__proto__:File
In service.js:
function($http, $q) {
return {
uploadData : function(baseUrl, data) {
var fd = new FormData();
/*for(var key in data)
fd.append(key,data[key]);*/
fd.append("file", data);
console.log('fd:' + fd);
var name="Meenu";
return $http.post(baseUrl+'/data/fileupload', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
}).then(
function successCallback(response){
alert('Response: '+response.data);
},function errCallback(errResponse){
alert('Error: '+errResponse.data);
alert('Error: '+errResponse.status);
});
},
}
}
In controller.java:
#RequestMapping(value = "/data/fileupload", method = RequestMethod.POST)
#ResponseBody
public String postFile(#RequestParam(value = "file",required=false) MultipartFile file) {
try {
System.out.println("name = " + file);
} catch (Exception e) {
e.printStackTrace();
}
return "OK";
}
I am getting null value for 'file'. Please let me know how can we receive the file from http request in controller.java.

File download/save from a Jersey rest api call using ANGULARJS . file is attached with response as "Content-Disposition"

I am new to angular .. I hava java rest api which return CSV file in response as attachment as | "Content-Disposition", "attachment; filename=" | content-type :application/octet-stream
Now when i am calling this api from AngularJS using $http i am getting response.data ="" (blank)
I am using basic authorisation for security so I have to pass Header while calling calling API so can't use link click or new window open fro CSV download.
to test when i removed authorisation and hit the url in browser then CSV file is being downloaded.so no issue at server side .
I need help at angularjs side to download CSV file from web api response as attachment.
Here is my Java API Code
public class ServiceAPI {
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFileAsCSVFile(){
byte[] file=null;
try {
ArrayList<> List=new ArrayList<>();// data retrieved from DB
if(null != List){
file=convertJsonToCSV(new Gson().toJson(List));
}
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Response.ok(getBytes(file),MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=" + "FileName.csv").build();
}
}
and Angular code :
app.controller('review', ['$scope', '$http', function ($scope, $http){
$scope.fromDate = new Date();
$scope.toDate = new Date();
$scope.minDate = new Date(
$scope.fromDate.getFullYear(),
$scope.fromDate.getMonth() - 2,
$scope.fromDate.getDate(),
$scope.toDate.getFullYear(),
$scope.toDate.getMonth() - 2,
$scope.toDate.getDate()
);
$scope.maxDate = new Date(
$scope.fromDate.getFullYear(),
$scope.fromDate.getMonth() - 2,
$scope.fromDate.getDate(),
$scope.toDate.getFullYear(),
$scope.toDate.getMonth() - 2,
$scope.toDate.getDate()
);
$scope.reviews = json;
function openSaveAsDialog(filename, content, mediaType) {
var blob = new Blob([content], {type: mediaType});
saveAs(blob, filename);
}
function callApi(url) {
// var dat=apiFactory.getServiceData(url);
// console.log(dat);
// apiFactory.getServiceData(url);
var responseType='arraybuffer';
var expectedMediaType='application/octet-stream';
$http.get(url, {
headers: {
accept: expectedMediaType
},
responseType:responseType,
cache: true,
transformResponse: function (data) {
var pdf;
if (data) {
pdf = new Blob([data], {
type: expectedMediaType
});
}
return {
response: pdf
};
}
}).then(function (data,status,headers) {
var filename='Preview.csv',
octetStreamMime = "application/octet-stream",
contentType;
headers = data.headers();
contentType = headers["content-type"] || octetStreamMime;
// openSaveAsDialog(filename, response.data, expectedMediaType);
if (navigator.msSaveBlob) {
var blob = new Blob([data], { type: contentType });
navigator.msSaveBlob(blob, filename);
} else {
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (urlCreator) {
// Try to use a download link
var link = document.createElement("a");
if ("download" in link) {
// Prepare a blob URL
var blob = new Blob([data.data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
// Simulate clicking the download link
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(event);
} else {
// Prepare a blob URL
// Use application/octet-stream when using window.location to force download
var blob = new Blob([data], { type: octetStreamMime });
var url = urlCreator.createObjectURL(blob);
$window.location = url;
}
}
}
});
};
$scope.submit = function (fromDate, toDate) {
$scope.url = API_url;
var resp =callApi(($scope.url).split(" ").join("%20"));
console.log(resp);
};
},
]);
I have an example with spring MVC instead of JAX-RS (Jersey)
HTML:
<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>
Angularjs controler:
$scope.downloadCsv = function () {
console.log("downloadCsv");
var fileName = "test.csv";
var a = document.createElement("a");
document.body.appendChild(a);
XxxxxxServiceCSV.downloadCsv().then(function (result) {
console.log("downloadCsv callback");
var file = new Blob([result.data], {type: 'application/csv'});
var fileURL = URL.createObjectURL(file);
a.href = fileURL;
a.download = fileName;
a.click();
});
};
Angularjs services:
angular.module('xxxxxxxxApp')
.factory('XxxxxxServiceCSV', function ($http) {
return {
downloadCsv: function () {
return $http.get('api/downloadCSV', { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
};
});
Java code JAX-RS(spring MVC):
#RequestMapping(value = "/downloadCSV", method = RequestMethod.GET, produces = "application/csv")
public void demo(HttpServletResponse response) throws IOException {
List<String> names = new ArrayList<String>();
names.add("First Name");
names.add("Second Name");
names.add("Third Name");
names.add("Fourth Name");
BufferedWriter writer = new BufferedWriter(response.getWriter());
try {
response.setHeader("Content-Disposition", "attachment; filename=\"test.csv\"");
for (String name : names) {
writer.write(name);
writer.write(",");
}
writer.newLine();
} catch (IOException ex) {
} finally {
writer.flush();
writer.close();
}
}

Categories

Resources