I would like to upload file to my web server.
My server implement RESTful API.
To upload file i should pass 4 parameters: file, file_name, project, version
I would like to upload file with this 3 parameters from console. I tried this
URL obj = new URL(MY_URL);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(con.getOutputStream());
ToSend send = new ToSend();
send.file = Files.readAllBytes(Paths.get("path"));
send.file_name = "name";
send.project = "test";
send.version = "1";
objectOutputStream.writeObject(send);
objectOutputStream.flush();
objectOutputStream.close();
and the object i send look like this
class ToSend implements Serializable {
byte[] file;
String file_name;
String project;
String version;
}
I get Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL:
If this is important my server written in Java+Spring and method for this has next signature
#RequestMapping(value = "/", method = RequestMethod.POST)
public #ResponseBody
Response<Boolean> upload(
#RequestParam("project") String project,
#RequestParam("version") String version,
#RequestParam("file_name") String fileName,
#RequestParam("file") MultipartFile file
) throws ServiceException, BadFileExtension {
boolean success = storageService.uploadFile(file, project, fileName, version);
return builder.get(success);
}
This solutions works for me. Maybe useful for someone too.
http://www.codejava.net/java-se/networking/upload-files-by-sending-multipart-request-programmatically
Related
Hello I am building an application in Spring Boot and Thymeleaf and I have an upload page where I have two fields and an upload button. I complete the fields and I select and xml and send it to the api and the answer I receive back is that the file is not valid. The response is written by the api creator so probably what I am thinking I am not reading the file right before sending.
Here is my code:
Service:
public String upload(String standard, String cif, MultipartFile file) throws
IOException {
String url = "http://100.000:222/test/upload?standard="+standard+"&cif="+cif;
String content = file.toString();
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
String text = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
HttpHeaders headers = new HttpHeaders();
headers.add("serial", "123");
headers.add("Content-Disposition", "text/xml");
headers.add("fisier", text);
RestTemplate restTemplate = new RestTemplate();
RequestEntity<Void> request = (RequestEntity<Void>) RequestEntity.get(URI.create(url))
.headers(headers)
.build();
String response = restTemplate.postForObject(url, request, String.class);
return response;
}
Here is the controller:
#PostMapping("/upload")
public String postUpload(#RequestParam("standard") String standard, #RequestParam("select") String select, #RequestParam("fisier") MultipartFile file, Model model) throws IOException {
String index = service.upload(standard, select, file);
System.out.println(index);
model.addAttribute("index", index);
return "upload";
}
This is the message I am getting back:
<header xmlns = "xxx: xxx: xxx: xx: respUploadFile: v1" dateResponse = "202205311034" ExecutionStatus = "1">
<Errors errorMessage = "The transmitted file is invalid. Org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog." />
</header>
Can someone tell me what I am doing wrong or give me an working example. Thanks
I want to send mail with an attachment through Mailjet in java. I have no problem while sending simple mail without attachment but when I try to add attachment I am getting this error:
400
[{"ErrorIdentifier":"314408e7-e528-469f-9361-2eb3c24b2b32","ErrorCode":"mj-0004","ErrorRelatedTo":["Messages.Attachments"],"ErrorMessage":"Type mismatch. Expected type \"Attachments\".","StatusCode":400}]
And my code looks like this:
#Service
public class MailJetSenderImp implements MailJetSender {
Message message = new Message();
#Override
public ResponseEntity<Message> sendMail(String To, String Body, String Subject, File attachment) throws MailjetSocketTimeoutException, JSONException, IOException {
FileInputStream fileInputStream = new FileInputStream(attachment);
int byteLength=(int) attachment.length(); //bytecount of the file-content
byte[] filecontent = new byte[byteLength];
fileInputStream.read(filecontent,0,byteLength);
byte[] encoded = Base64.getEncoder().encode(filecontent);
MailjetRequest email = new MailjetRequest(Emailv31.resource)
.property(Emailv31.MESSAGES, new JSONArray()
.put(new JSONObject()
.put(Emailv31.Message.FROM, new JSONObject()
.put("Email","xxxxxx#gmail.com" )
.put("Name", "xxxxx"))
.put(Emailv31.Message.TO, new JSONArray()
.put(new JSONObject()
.put("Email", To)))
.put(Emailv31.Message.SUBJECT, Subject)
.put(Emailv31.Message.TEXTPART, "")
.put(Emailv31.Message.HTMLPART, Body)
.put(Emailv31.Message.ATTACHMENTS,encoded)));
final String mailjetApiKey = "xxxxxxxx";
final String mailjetSecretKey = "yyyyyyyy";
MailjetClient client = new MailjetClient(
mailjetApiKey, mailjetSecretKey, new ClientOptions("v3.1"));
try {
// trigger the API call
MailjetResponse response = client.post(email);
// Read the response data and status
System.out.println(response.getStatus());
System.out.println(response.getData());
message.setCode(response.getStatus());
message.setMessage(response.getData().toString());
return ResponseEntity.status(HttpStatus.OK).body(message);
} catch (MailjetException e) {
System.out.println("Mailjet Exception: " + e);
message.setCode(400);
message.setMessage("could not send email");
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(message);
}
}
}
I get error message on (.put(Emailv31.Message.ATTACHMENTS,encoded)));
Here is the Java code to send the mail attachment
The ATTACHMENTS data is a JSON array containing 3 fields:
ContentType - Content type of the attachment
Filename - name of the file attachment that the receiver would see
Base64Content - Base64 encoded file data as String
So, encode the file content as String ( I used the Base64 encoder from mailjet client JAR itself here ). filecontent is the byte[]. A hardcoded PDF file code sample below :
java.nio.file.Path pdfPath =
java.nio.file.Paths.get("c:\\D\\sample.pdf");
byte[] filecontent = java.nio.file.Files.readAllBytes(pdfPath);
String fileData = com.mailjet.client.Base64.encode(filecontent);
Next, use this code to send the attachment, your other code remains same.
Example here is for a PDF file, choose your MIME type correctly
.put(Emailv31.Message.ATTACHMENTS,
new JSONArray().put(new JSONObject().put("ContentType", "application/pdf")
.put("Filename", "abc.pdf")
.put("Base64Content", fileData)))
.put(Emailv31.Message.HTMLPART,...
Below is the server side code for sending file to client as rest response using micronaut.
#Get(value = "/downloadFile", produces = MediaType.APPLICATION_OCTET_STREAM )
public HttpResponse<File> downloadDocument() throws IOException {
File sampleDocumentFile = new File(getClass().getClassLoader().getResource("SampleDocument.pdf").getFile());
return HttpResponse.ok(sampleDocumentFile).header("Content-Disposition", "attachment; filename=\"" + sampleDocumentFile.getName() + "\"" );
}
Below is the client for calling the above endpoint.
#Client(value = "/client")
public interface DownloadDocumentClient {
#Get(value = "/downloadDocument", processes = MediaType.APPLICATION_OCTET_STREAM)
public Flowable<File> downloadDocument();
}
Tried to retreive file as below :-
Flowable<File> fileFlowable = downloadDocumentClient.downloadDocument();
Maybe<File> fileMaybe = fileFlowable.firstElement();
return fileMaybe.blockingGet();
Getting exception as
io.micronaut.context.exceptions.ConfigurationException: Cannot create
the generated HTTP client's required return type, since no
TypeConverter from ByteBuffer to class java.io.File is registered
You cannot send file data using File instance because it contains only path and not file content. You can send file content using byte array.
Update the controller in this way:
#Get(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM)
public HttpResponse<byte[]> downloadDocument() throws IOException, URISyntaxException {
String documentName = "SampleDocument.pdf";
byte[] content = Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource(documentName).toURI()));
return HttpResponse.ok(content).header("Content-Disposition", "attachment; filename=\"" + documentName + "\"");
}
Client will be then like this:
#Get(value = "/download", processes = MediaType.APPLICATION_OCTET_STREAM)
Flowable<byte[]> downloadDocument();
And finally client call:
Flowable<byte[]> fileFlowable = downloadDocumentClient.downloadDocument();
Maybe<byte[]> fileMaybe = fileFlowable.firstElement();
byte[] content = fileMaybe.blockingGet();
Update:
If you need to save received bytes (file content) into the file on a client machine (container) then you can do that for example like this:
Path targetPath = Files.write(Paths.get("target.pdf"), fileMaybe.blockingGet());
And if you really need instance of File instead of Path for further processing then simply:
File file = targetPath.toFile();
service code:
#RequestMapping(value="/uploadFile", method=RequestMethod.POST, consumes = "multipart/form-data")
public String uploadFile(#RequestParam("file") MultipartFile file,#RequestParam("filePath") String filePath){
//logic here
}
Part of the client code:
public static synchronized String responseOfPost(String restUrl, FileSystemResource file,String filePath) {
PostMethod post = new PostMethod(restUrl);
HttpClient client = new HttpClient();
post.setParameter("filePath", filePath);
try {
Part[] parts = {new FilePart("file",file.getFile())};
post.addRequestHeader("Content-Type", "multipart/form-data; boundary=Endedlogging");
if (file != null) {
post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
}
client.executeMethod(post);
String response = post.getResponseBodyAsString();
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
this is the error I am getting:
org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
How can I pass multipart file("file") and filePath("filePath") to POST method in client code? NOT FROM UI
I'm also getting the exception like FileNotFoundException with nearly same code as your's.So can you try with this change,it maybe helpful.
Part[] parts = {new FilePart(file.getName(),file)};
I have below client code:
String filePath = "/testzip/123/TEST-test.zip";
target = mainTarget.path("file").path("{filePath}");
Invocation.Builder invocationBuilder = target
.resolveTemplate("filePath", filePath)
.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_OCTET_STREAM);
Response response = invocationBuilder.get();
Below is my server code:
#GET
#Path("{filePath}")
#Produces({MediaType.APPLICATION_OCTET_STREAM})
public Response get(#PathParam("filePath") String filePath) {
File file = new File(filePath);
return Response.status(Response.Status.OK).entity(file).build();
}
This client is throwing Bad Request exception while I send below filePath:
String filePath = "/testzip/123/TEST-test.zip";
But it is working fine when I send below filePath (simple string):
String filePath = "testzip";
I am not able to figure it out why it is not working when forward slash(/) is present in path parameters.
I believe you cannot have / in a #PathParam by default.
EDIT Have a look here : Tomcat, JAX-RS, Jersey, #PathParam: how to pass dots and slashes?