i have an issue with getting the conent-disposition information from an uploaded file. The file upload itself is just working fine. But the Content-Disposition is null thats why i dont know the name and type ofthe uploaded file. I am triggering the post via angularJs's $http service.
#Path("/myrest")
#Service
public class RestService<Repsonse> {
private static final String SERVER_UPLOAD_LOCATION_FOLDER = "C://Users/steven/Desktop/upload/";
/**
* Upload a File
*/
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
#FormDataParam("myForm") InputStream fileInputStream,
#FormDataParam("myForm") FormDataContentDisposition fileDetail
) {
if (fileDetail == null) {
System.out.println("form contentDispositionHeader is null");
// return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(Response.Status.INTERNAL_SERVER_ERROR.toString()).build();
} else {
System.out.println("form: " + fileDetail.toString());
}
Random randomno = new Random();
// String filePath = SERVER_UPLOAD_LOCATION_FOLDER + contentDispositionHeader.getFileName();
// String filePath = SERVER_UPLOAD_LOCATION_FOLDER + "bla.png";
String filePath = SERVER_UPLOAD_LOCATION_FOLDER + "test" + randomno.nextInt(10000) + ".jpg";
// save the file to the server
saveFile(fileInputStream, filePath);
String output = "File saved to server location : " + filePath;
return Response.status(200).entity(output).build();
}
// save uploaded file to a defined location on the server
private void saveFile(InputStream uploadedInputStream,
String serverLocation) {
OutputStream outpuStream = null;
try {
outpuStream = new FileOutputStream(new File(serverLocation));
int read = 0;
byte[] bytes = new byte[1024];
outpuStream = new FileOutputStream(new File(serverLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
outpuStream.write(bytes, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(outpuStream != null) {
uploadedInputStream.close();
}
if(outpuStream != null) {
outpuStream.flush();
outpuStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The angularJs part:
js:
var file = $scope.myFile;
that.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
return $http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
});
};
The html part:
<div ng-controller="fileUploadController">
input type="file" file-model="myFile"/>
<br>
<br>
Name: {{myFile.name}} <br>
Size: {{myFile.size}} <br>
Type: {{myFile.type}} <br>
<br>
<br>
<button ng-click="uploadFile();">Upload</button>
</div>
Uploading files with ajax is in XHR level 2 spec and not really supported by all browsers...
Prefer an approach like $.fileUpload ( https://blueimp.github.io/jQuery-File-Upload/ ) for sending file in an angular/ one-page application.
If you do know what you are going, just add file.name or file.fileName in another field of your FormData object and get it that way server-side.
Related
I have images on machine of server. I want to retrieve image and display it in UI using angularjs.
I convert image to byte array in RestController. In angularjs, I send a request to get byte array then display byte array as an image in html. But image do not show on web page. Below is my code:
#RequestMapping(value = "/images", method = RequestMethod.GET)
public ResponseEntity<byte[]> getProductImage(String fileName) {
byte[] result = null;
File serverFile;
try {
serverFile = productService.getProductImage(fileName);
BufferedImage bufferedImage = ImageIO.read(serverFile);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
result = (data.getData());
} catch (IOException e) {
e.printStackTrace();
}
String mimeType = URLConnection.guessContentTypeFromName(fileName);
HttpHeaders headers = null;
if (mimeType != null) {
headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(mimeType));
}
return new ResponseEntity<>(Base64.getEncoder().encode(result), headers, HttpStatus.OK);
}
angularjs
vm.getByte = function(fileName){
$http({
method: 'GET',
url: '/api/images',
params: {
fileName: fileName
}
}).success(function(success){
vm.imgFile = success;
});
};
html code
<div class="form-group">
<label>Image</label>
<div class="form-group has-avatar" ng-if="vm.Product.productImg">
<img ng-src="data:image/JPEG;base64,{{vm.imgFile}}" style="width: 200px;height: 130px;" />
current result:
result
You should fix code in java follow:
#RequestMapping(value = "/images", method = RequestMethod.GET)
public ResponseEntity<byte[]> getProductImage(String fileName) {
byte[] result = null;
File serverFile;
try {
serverFile = productService.getProductImage(fileName);
FileInputStream fi = new FileInputStream(serverFile);
result = Base64.getEncoder().encode(IOUtils.toByteArray(fi));
} catch (IOException e) {
e.printStackTrace();
}
String mimeType = URLConnection.guessContentTypeFromName(fileName);
HttpHeaders headers = null;
if (mimeType != null) {
headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(mimeType));
}
return new ResponseEntity<>(result, headers, HttpStatus.OK);
}
really don't now what to do.
i have on my server xls file and i wont to download it from my client.
i actually do it but the file getting in some weird langue and absolutely broken.
client : angular
server: spring 4
Code
Client
function getXCEL() {
self.onXCELProcess = true;
AdminService.getXL(MotherService.getAppMember())
.then(
function (response) {
var file = new Blob([response], {type: 'application/excel'});
var isChrome = !!window.chrome && !!window.chrome.webstore;
var isIE = /*#cc_on!#*/false || !!document.documentMode;
var isEdge = !isIE && !!window.StyleMedia;
if (isChrome){
var url = window.URL || window.webkitURL;
var downloadLink = angular.element('<a></a>');
downloadLink.attr('href',url.createObjectURL(file));
downloadLink.attr('target','_self');
downloadLink.attr('download', 'yourReports.xls');
downloadLink[0].click();
}
else if(isEdge || isIE){
window.navigator.msSaveOrOpenBlob(file,'yourReports.xls');
}
else {
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
self.onXCELProcess = false;
},
function (error) {
console.error("error : "+error+" , error : "+JSON.stringify(error));
self.onXCELProcess = false;
}
)
}
function getXL(admin) {
return MotherService.callToServer({method: 'POST', url: URL + "orderxl", appMember: admin});
}
callToServer() method do request, with json body. and return the deferred.promise
for use of then.
server
#RequestMapping(value = "/"+Request.ADMIN_PATH+"/"+Request.ORDER_XL, method = RequestMethod.POST)
public void getFile(#RequestBody OrderXLRequest request, HttpServletResponse response) {
try {
File file = orderXLService.execute(request).getFile(); //get the file. already saved and ready to send
try{
InputStream inputStream = new FileInputStream(file);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", "excelfilename.xlsx");
response.setHeader(headerKey, headerValue);
try {
FileCopyUtils.copy(inputStream, response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}catch(Exception e){
System.out.println("Exception in file download :"+e);
}
}catch (Exception e) {
e.printStackTrace();
}
}
thank you very much for any help or suggestion
I have created simple rest method to upload and add file via multipart in Spring Boot.
I don't have any #RequestBody so I'm quite astonished why the browser throws 415 -> "Unsupported Media Type" Content type 'null' not supported
The controller looks like:
#RestController
#RequestMapping(value = "/api/file")
public class FileController {
#Autowired
private FileServiceImpl fileService;
#Autowired
private UserRepository userRepository;
#PreAuthorize("hasAnyAuthority('CLIENT')")
#RequestMapping(value = "", method = RequestMethod.POST, headers = "content-type=multipart/*", produces = "application/json", consumes = MediaType.APPLICATION_JSON_VALUE)
public File uploadFile(#RequestParam("uploadedFile") MultipartFile file, HttpServletRequest httpRequest) {
Principal name = httpRequest.getUserPrincipal();
if (name.getName() == null) {
throw new RuntimeException("Brak sesji");
}
User userByLogin = userRepository.findUserByLogin(name.getName());
File f = null;
if (!file.isEmpty()) {
try {
f = new File(file.getOriginalFilename(), file.getBytes(), file.getName(), file.getContentType(), new Date(), userByLogin);
} catch (IOException e) {
e.printStackTrace();
}
}
if (f != null) {
fileService.uploadFile(f);
}
return f;
}
}
At the frontend looks like
<div>
<label>Dodaj załącznik</label>
<input type="file" files-model="file" >
<button ng-click="addFile()">Dodaj</button>
</div>
$scope.addFile = function () {
FileService.save($scope.file);
}
The fail looks like:
{"timestamp":1491988354597,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'null' not supported","path":"/api/file"}
you have to append your file in formData.
<div>
<label></label>
<input type="file" files-model="file" id="file" >
<button ng-click="addFile()">Dodaj</button>
</div>
$scope.addFile = function () {
var file = document.getElementById("file").files[0];
var formData = new FormData();
formData.append("file", file);
FileService.save(formData);
};
In FileService service you have to set headers: {Content-Type:undefined}
this should work!
I am new in springs and I want to upload the file in server. But it didn't save the file in that particular format..help me....
here is my jsp page.
<html>
<head>
<title>Upload File Request Page</title>
</head>
<body>
<form method="POST" action="uploadFile" enctype="multipart/form-data">
File to upload: <input type="file" name="file"><br><br>
<!-- Name: <input type="text" name="file"><br> <br> -->
<input type="submit" value="Upload"> Press here to upload the file!
</form>
</body>
</html>
and controller file.
public class FileUploadController
{
private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);
/**
* Upload single file using Spring Controller
*/
#RequestMapping(value = "/upload", method = RequestMethod.GET)
public String upload(Locale locale, Model model)
{
logger.info("upload");
return "upload";
}
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public #ResponseBody String uploadFileHandler(#RequestParam(value = "name", required = false) String name,
#RequestParam("file") MultipartFile file)
{
if (!file.isEmpty())
{
try
{
byte[] bytes = file.getBytes();
// Creating the directory to store file
String rootPath = System.getProperty("catalina.home");
File dir = new File(rootPath + File.separator + "tmpFiles/abc");
if (!dir.exists())
dir.mkdirs();
// Create the file on server
File serverFile = new File(dir.getAbsolutePath() + File.separator + name);
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(name));
stream.write(bytes);
stream.close();
logger.info("Server File Location=" + serverFile.getAbsolutePath());
return "You successfully uploaded file=" + name + "!";
} catch (Exception e)
{
return "You failed to upload " + name + " => " + e.getMessage();
}
}
else
{
return "You failed to upload " + name + " because the file was empty.";
}
}
controller page
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public #ResponseBody String uploadFileHandler(#RequestParam(value = "name", required = false) String name,
#RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
System.out.println(">>>>"+ file.getOriginalFilename());
byte[] bytes = file.getBytes();
// Creating the directory to store file
String rootPath = System.getProperty("catalina.home");
System.out.println(">"+rootPath);
File dir = new File(rootPath + File.separator + "tmpFiles/abc");
if (!dir.exists())
dir.mkdirs();
// Create the file on server
File serverFile = new File(dir.getAbsolutePath() + File.separator + file.getOriginalFilename());
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
stream.write(bytes);
stream.close();
logger.info("Server File Location=" + serverFile.getAbsolutePath());
return "You successfully uploaded file=" + file.getOriginalFilename();
} catch (Exception e) {
return "You failed to upload " + file.getOriginalFilename() + " => " + e.getMessage();
}
} else {
return "You failed to upload " + file.getOriginalFilename() + " because the file was empty.";
}
}
Server side
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> Post()
{
// Check whether the POST operation is MultiPart?
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
// Prepare CustomMultipartFormDataStreamProvider in which our multipart form
// data will be loaded.
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
List<string> files = new List<string>();
try
{
// Read all contents of multipart message into CustomMultipartFormDataStreamProvider.
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData file in provider.FileData)
{
files.Add(Path.GetFileName(file.LocalFileName));
}
// Send OK Response along with saved file names to the client.
return Request.CreateResponse(HttpStatusCode.OK, files);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
Client side code, After I get the imageURI from camera send it to below
function send(imageURI) {
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
options.chunkedMode = false;
options.headers = {
Connection: "close"
}
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://localhost/api/api/upload"), win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
alert("upload error source " + error.source);
alert("upload error target " + error.target);
}
I get error code 1 on the fail function. is their anything wrong with server side code? can I send ImageURI the above web api i wrote?
the code seemed to be working fine. The server user which was set on IIS did not have the proper permissions to do the write hence it was returning error. thanks