/rest/api/3/issue/{issue-key}/attachments, upload file with a Chinese name, name turn to messy code

Bai Jing April 29, 2019

/rest/api/3/issue/{issue-key}/attachments, upload file with a Chinese name, name turn to messy code

I try this with Unirest http client

String imageAPIEndpoint = "https://mydomain.atlassian.net/rest/api/3/issue/key-123/attachments",
File f = new File("D:\\中文.png");
InputStream in =new FileInputStream(f);
String fileName = f.getName();
HttpResponse<JsonNode> uploadResponse = Unirest.post(imaggaAPIEndpoint)
.header("X-Atlassian-Token","no-check")
.header("Accept","application/json")
.basicAuth("myCount","token")
.field("file",in,"abc中文")
.asJson();

200
[{"filename":"abc??","size":50399,"author":{"accountId":

abc中文 turn to abc?? ( or other messy code) 

1 answer

1 accepted

0 votes
Answer accepted
Earl McCutcheon
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
April 30, 2019

Hello,

I did a quick check on the API endpoint to make sure the call would go through without an issue and doing a direct Curl to the endpoint is working without triggering this behavior, so error you are encountering looks to be something in the formatting of the Unirest input values.

Testing this out I used the following CURL format with a cloud API token for basic auth:

curl -D- -u user:token -X POST -H "X-Atlassian-Token: no-check" -F "file=@中文.png" https://mydomain.atlassian.net/rest/api/3/issue/key-123/attachments

And the file uploaded correctly without converting the non-ASCII values to question marks:

Screen Shot 2019-04-30 at 11.57.53 AM.png

I did not have the maven library installed to do a full test but looking at the documentation for Unirest at the following link:

It looks like it may be the formatting for the file input string missing some parenthesis as the example is:

.field("file", new File("/tmp/file"))

Can you try modifying the script to 

.field("file",abc中文.png(in))

And if that does not work try removing the "in" variable and test with a direct syntax input to see if we can bypass the issue with something like:

HttpResponse<JsonNode> uploadResponse = Unirest.post(imaggaAPIEndpoint)
.header("X-Atlassian-Token","no-check")
.header("Accept","application/json")
.basicAuth("myCount","token")
.field("file",abc中文.png("path/to/abc中文.png"))
.asJson();

Regards,
Earl

Bai Jing May 6, 2019

Hi, Earl:

Thanks so much for the detailed reply.

I tested the endpoint /rest/api/3/issue/{issue-key}/attachments with curl and postman, and that worked fine.

Finally, I found the reason of the "messy code".

It's a defect  of com.mashape.unirest 1.4.9

<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>

https://github.com/OpenUnirest/unirest-java/issues/35

https://github.com/OpenUnirest/unirest-java/pull/33#issuecomment-412890167

I try io.github.openunirest open-unirest-java 3.3.06

<!-- https://mvnrepository.com/artifact/io.github.openunirest/open-unirest-java -->
<dependency>
<groupId>io.github.openunirest</groupId>
<artifactId>open-unirest-java</artifactId>
<version>3.3.06</version>
</dependency>

This lib works  perfectly.

[{"thumbnail":"https://mydomain.atlassian.net/secure/thumbnail/93836/%E4%B8%AD%E6%96%87.png","filename":"中文.png","size":50399,"a.......

Thanks again for the quick reply and I hope this may help other friends.

Best Regards

:)

Like # people like this
Earl McCutcheon
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
May 6, 2019

Thanks for sharing the follow up info, that was really helpful :)

박주형 June 20, 2022

You can change File name

I use okhttp

 

OkHttpClient client = new OkHttpClient.Builder()
.authenticator(getAuthenticator(userId, password))
.build();

RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getOriginalFilename(), RequestBody.create(MediaType.parse("application/octet-stream"), file.getBytes()))
// .addFormDataPart("file", file.getOriginalFilename(), RequestBodyUtil.create(MediaType.parse("application/octet-stream"), f))
.build();

Request request = new Request.Builder()
.url(apiUrl)
.method("POST", body)
.addHeader("Accept", "application/json;charset=UTF-8")
.addHeader("X-Atlassian-Token", "no-check")
.build();


private static Authenticator getAuthenticator(final String userId, final String password){
return (route, response) ->{
String credential = Credentials.basic(userId, password);
return response.request().newBuilder().header("Authorization", credential).build();
};
}
 

Suggest an answer

Log in or Sign up to answer