I am not able to display an image stored as blob returned by a rest service :
This is the rest service code that returns the blob stored image coded into base64 :
#GET
#Path("/get")
#Produces("image/jpeg")
public Response getFile() {
String base64 = getStringImage();
ResponseBuilder response = Response.ok((Object) base64);
return response.build();
}
String getStringImage() {
try {
AnounceService anounceService = (AnounceService)getApplicationContext().getBean("AnounceService");
Blob imageBlob = anounceService.getStgImage();
int blobLength = (int)imageBlob.length();
byte[] buff = imageBlob.getBytes(1, blobLength);
String base64=Base64Utils.toBase64(buff);
return base64;
} catch (Exception exc) {
}
return null;
}
This is the gwt client code that fails to display the image returned by the above rest code :
String url = "root/api/image/get";
final RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);Image img;
builder.setCallback(new RequestCallback() {
public void onResponseReceived(final Request request, final Response response) {
if (response.getStatusCode() == Response.SC_OK) {
final HTML imageHolder = new HTML();
String base64 = response.getText();
String imgTag = "<img src='data:image/gif;base64,"+base64+"' />'";
imageHolder.setHTML(imgTag);
RootPanel.get().add(imageHolder);
}
}
There is no error triggered, but I don't see any image displayed in the browser.
Related
i am trying to post multiple images with array but i am not able to send it into server because its shows some error
when i am trying to send images converted into bitmap it goes into onFailure method and shows error like below
error returns bitmap
D/Onfail: /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCACKAIoDASIA
AhEBAxEB/8QAHgABAAIDAQADAQAAAAAAAAAAAAUIBgcJAwECBAr/xABSEAABAgIFAhEGCAsJAAAA
AAAEAAUDBgECBxQVESEIExgkJTE1QVFVV2FxlJXR1BYjNER1oRIXM0VUgZGWNzhDWGRlsbbF1fAm
NlNWpbXB4fH/xAAYAQEBAQEBAAAAAAAAAAAAAAAAAgQDBf/EACIRAQAABAYDAQAAAAAAAAAAAAAB
AxPhAkFhcpHBESGhcf/aAAwDAQACEQMRAD8A/toREWh44iIgIiICIiAiIgIiICIiAiIgIiICIiAi
IgIiwmd5/lGztqqPc4vENqDrxLqL5oqOcYR9FEFC2QN78ufaQZsirJqtrDePXX7uOng01W1hvHrr
93HTwaOdPX5dZtFWTVbWG8euv3cdPBpqtrDePXX7uOng0Kevy6zaKsmq2sN49dfu46eDWxbP7ZbO
bSiDA5Sfr4eHC02K3mClAHXf6UIIbnO3tvLv50dG1kREBERAREQEREBERAVDdE2KM620WDsjlBvj
U4OjOAe3kZdIjDmTQGGXm4HEHhp+tXyVEtEX+HvQ+e3ZW/fIVEyst0OmSWrEaGayUgMB+s0Y3J3c
BaSoTUzsDWRHgj0etF37DW8Kn3cFKyWy9j0N9qzQS6yxZ9LdSI3xbo6N7gwCwDhCM90vfDno28/7
VonRYWQT09TpUneWmR0mVrMa28AkdnFKdjm0gPNuSFr+47XRz051sjQjWVzdJAczzDNYBjHXmSE3
igM5nmDruHfNcliZrjmL+uj36FN8/EZY7ycSd2ML3L4+Iyx3k2k/sYRZ5MUxM8qMx8xTCdDbGtrh
XsoiLt/b0UZ865rO2i8nWJaHBmFqqfAkoO8AQpXibbkz0F066LL26Hyn/Sqd/O6IL3fEZY7ycSd2
ML3KqcaXWSTtF9JTVKrUGwNpDNpsVua4VMCBTfJWmO9602/VBM9O97rqyTOsuz/L4c0S2bfG0z8n
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
this is my post method
private void PostInfo() {
bitmap = ((BitmapDrawable) defoult.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT);
ArrayList<String> filePaths = new ArrayList<>();
filePaths.add(imageString);
Log.d("strinimagess",imageString);
//filePaths.add("file:///storage/emulated/0/DCIM/Camera/IMG_20191207_131304.jpg");
// filePaths.add("file:///storage/emulated/0/DCIM/Camera/IMG_20191207_131300.jpgg");
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("skill_years", nameField.getText().toString());
builder.addFormDataPart("skill_where", nameField1.getText().toString());
builder.addFormDataPart("about_work", nameField2.getText().toString());
builder.addFormDataPart("skill_id", skill_id);
builder.addFormDataPart("user_id", user_id);
for (int i = 0; i < filePaths.size(); i++) {
File file = new File(filePaths.get(i));
builder.addFormDataPart("skill_images", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file));
}
MultipartBody requestBody = builder.build();
jsonObject = new JsonObject();
jsonObject.addProperty("skill_years", nameField.getText().toString());
jsonObject.addProperty("skill_where", nameField1.getText().toString());
jsonObject.addProperty("about_work", nameField2.getText().toString());
jsonObject.addProperty("skill_id", skill_id);
jsonObject.addProperty("user_id", user_id);
jsonObject.addProperty("skill_images", String.valueOf(myImageList));
RetrofitInterface jsonpost = ServiceGenerator.createService(RetrofitInterface.class,"http://littletreasure.org.in/");
Call<InFo_Post> call = jsonpost.post(requestBody);
call.enqueue(new Callback<InFo_Post>() {
#Override
public void onResponse(Call<InFo_Post> call, retrofit2.Response<InFo_Post> response) {
if (response.isSuccessful()){
Log.d("response", String.valueOf(response.body().getMsg()));
Toast.makeText(Info.this, "success", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<InFo_Post> call, Throwable t) {
Log.d("Onfail",t.getMessage());
Toast.makeText(Info.this, "failed", Toast.LENGTH_SHORT).show();
}
});
this is my Info Post model class
public class InFo_Post {
private String status;
private String msg;
private DataModel data;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public DataModel getData() {
return data;
}
public void setData(DataModel data) {
this.data = data;
}
private class DataModel {
private String skill_years;
private String skill_where;
private String about_work;
private String skill_images;
public String getSkill_years() {
return skill_years;
}
public void setSkill_years(String skill_years) {
this.skill_years = skill_years;
}
public String getSkill_where() {
return skill_where;
}
public void setSkill_where(String skill_where) {
this.skill_where = skill_where;
}
public String getAbout_work() {
return about_work;
}
public void setAbout_work(String about_work) {
this.about_work = about_work;
}
public String getSkill_images() {
return skill_images;
}
public void setSkill_images(String skill_images) {
this.skill_images = skill_images;
}
}
}
i wrote a method that takes array of paths for images and return array of StringBase64
private ArrayList<String> imagesBase64(ArrayList<String> filePathes){
ArrayList<String> imagesBase64=new ArrayList<>();
for (int i = 0; i <filePathes.size() ; i++) {
Bitmap bm = BitmapFactory.decodeFile(filePathes.get(i));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
String imgString = Base64.encodeToString(b, Base64.NO_WRAP);
imagesBase64.add(imgString);
}
return imagesBase64;
}
but you must be sure your back-end receive array of Strings base64 to successfully upload it
Do you have just the bitmap or maybe you have also a file with that image ?
You can try create MultypartBody from data
private void sendFileToServer(String fileName) {
File file = new File(fileName);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
...
...
}
Also , don t forget in your WebService class to add annotation #Multipart at your post method
Make sure your API can handle a multiple files. Set your interface class with list of multipart files.
#Multipart
#POST("upload")
Call<ResponseBody> uploadMultipleFilesDynamic(
#Part("description") RequestBody description,
#Part List<MultipartBody.Part> files);
The second part of the implementation is using the new endpoint declaration and passing some files. Convert your files to multipart
#NonNull
private RequestBody createPartFromString(String descriptionString) {
return RequestBody.create(
okhttp3.MultipartBody.FORM, descriptionString);
}
#NonNull
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
File file = FileUtils.getFile(this, fileUri);
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}
MultipartBody.Part is used to send also the actual file name.
List<MultipartBody.Part> parts = new ArrayList<>();
if (photoUri != null) {
parts.add(prepareFilePart("photo", photoUri));
}
RequestBody description = createPartFromString("hello, this is description speaking");
// create upload service client
FileUploadService service = ServiceGenerator.createService(FileUploadService.class);
// finally, execute the request
Call<ResponseBody> call = service.uploadMultipleFilesDynamic(description, parts);
call.enqueue(...);
You can refer this official link : https://futurestud.io/tutorials/retrofit-2-how-to-upload-a-dynamic-amount-of-files-to-server
I am using Okhttp lib to send data to server. I want to set text and images in RequestBody. For uploading multiple image to server using Okhttp i follow this link. I have implemented that type of code in my app in another activity class and its work fine. I have checked this question that how to pass array in RequestBody.
My arrayList format is like this
blockList
{
block0
{
description0 = First block
image0 = {image1, image2}
video0 = videolink
disp_order0 = 0
block0 = 0
}
block1
{
description1 = second block
image1 = {image1,image2,image2}
video1 = videolink
disp_order1 = 1
block1 = 1
}
.....
}
My Requirement :-
Now i want to send multiple images as an array in single parameter. When i send first block then parameter names are description0,image0[],video1,disp_order and block0 and image0[] will contain first block images as array and same for other.
API is working fine because when i test in postman then i receive the data in server side. You can see in below..
Here is my java function that set the data in RequestBody and make a call to send that data on sever.
ProgressDialog pd;
private OkHttpClient client;
private void saveCastBoxOnServer(String castBoxTitle, String selectedCastBoxId, String selectedCategoryId,
String userId, String action, ArrayList<CastBoxBlock> blockList)
{
try
{
client = new OkHttpClient.Builder()
.retryOnConnectionFailure(true)
.build();
ArrayList<CastBoxBlock> blockArrayList = blockList;
int blockSize = blockArrayList.size();
MultipartBody.Builder multipartBuilderNew = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int i = 0; i < blockSize; i++)
{
String description = blockArrayList.get(i).getBlockDescription();
String descriptionField = "description"+i;
multipartBuilderNew.addFormDataPart(descriptionField, description);
/**This is used for distribution of images and videos. After that set that
* Images and video in multipartBuilder.
**/
CastBoxBlock model = blockArrayList.get(i);
ArrayList<SelectedMediaModel> mediaModels = model.getSelectedMediaModelArrayList();
int mediaModelsSize = mediaModels.size();
String passingVideoUri = "";
String videoUri = "";
for (int j = 0; j < mediaModelsSize; j++)
{
String mediaType = mediaModels.get(j).getMediaType();
if (mediaType.equals(StringKeyConstant.mediaVideo))
{
videoUri = mediaModels.get(j).getMediaPath();
if (passingVideoUri.trim().length()==0){
passingVideoUri = videoUri;
}else{
passingVideoUri = passingVideoUri + "," + videoUri;
}
}
else if (mediaType.equals(StringKeyConstant.mediaImage))
{
String imagePath = mediaModels.get(j).getMediaPath();
File sourceFile = new File(imagePath);
/**Changes whether JPEG or PNG**/
final MediaType MEDIA_TYPE = MediaType.parse(
constant.getFileExt(imagePath).endsWith("png") ? "image/png" : "image/jpeg");
String imageName = System.currentTimeMillis() + j + "_block_img.jpg";
String imageField = "image"+i+"["+j+"]";
multipartBuilderNew.addFormDataPart(imageField,imageName,
RequestBody.create(MEDIA_TYPE, sourceFile));
}
}
/**This is used to set the {#videoUri} block of videos and send to sever**/
String videoField = "video"+i;
multipartBuilderNew.addFormDataPart(videoField, passingVideoUri);
/**This will set the {#display_order} in multipartBuilder**/
String displayOrderField = "disp_order"+i;
String displayOrder = blockArrayList.get(i).getBlockIndex();
multipartBuilderNew.addFormDataPart(displayOrderField, displayOrder);
/**This will set the {#block} value in multipartBuilder**/
String blockField = "block"+i;
String block = ""+i;
multipartBuilderNew.addFormDataPart(blockField, block);
}
pd = new ProgressDialog(activity);
pd.setCancelable(false);
pd.setMessage(getResources().getString(R.string.please_wait));
pd.show();
RequestBody formBody = multipartBuilderNew
.addFormDataPart("cast_title", castBoxTitle)
.addFormDataPart("user_id", userId)
.addFormDataPart("cast_box", selectedCastBoxId)
.addFormDataPart("category", selectedCategoryId)
.addFormDataPart("action", action)
.build();
Request request = new Request.Builder()
.url(ApiUtils.ADD_FETCH_USER_CAST)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "Get Api credential fail."+call.toString());
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException
{
try
{
if (pd != null){
pd.cancel();
pd.dismiss();
pd = null;
}
String castSavedResponse = response.body().string();
Log.i(TAG, "castSavedResponse = " + castSavedResponse);
}
catch (Exception e){
Log.e(TAG, "***Error : onResponse() method");
e.printStackTrace();
}
}
});
}
catch (Exception e){
Log.e(TAG, "***Error : saveCastBoxOnServer()");
e.printStackTrace();
}
}
Thanks in advance. If any one will help it would be very appreciate.
When i check your code then i note one things. I am no sure but i think you change your code on image[] place. you can just change your code as below. I hope this will help you and you got the solution.
Use this code
String imageField = "image"+i+"[]";
Instead of
String imageField = "image"+i+"["+j+"]";
when i passed simple images as an array in Okhttp then i do code as above. For uploading multiple images on server using Okhttp, i also follow this link as you follow.
So I am getting a 400 for my HTTP response code when it should be 200. I am passing in a byte[] object to the endpoint but it doesn't seem to be adding the content-type correctly? Any suggestions?
#RequestMapping(value = "/test", method = RequestMethod.POST, consumes = "application/octet-stream")
public ResponseEntity<String> receiveCompressedBinary(#RequestHeader String site, #RequestHeader String customer,
#RequestHeader String table, #RequestBody byte[] binary, #RequestHeader String loadStatus) {
if(binary.length < maxFileSize) {
return new ResponseEntity<String>(HttpStatus.OK);
}
else{
return new ResponseEntity<String>(HttpStatus.PAYLOAD_TOO_LARGE);
}
}
My test:
#Test
public void testUploadCompressedBinaryInitialRunning() throws Exception{
File file = new File("src/test/resources/testFile.txt");
String site = "site";
String customer = "customer";
String table = "table";
String loadStatus = "INITIALRUNNING";
this.mockMvc.perform(post("/test").header("site",site).param("customer",customer).
param("table", table).content(compress(file)).param("loadStatus",loadStatus)
.with(user("user"))).andExpect(status().isOk());
this.mockMvc.perform(post("/uploadCompressedBinary")).andDo(print()).andExpect(status().isOk());
}
Compress method:
public static byte[] compress(File file) throws IOException {
if (file.length() == 0) {
return null;
}
FileInputStream fileInputStream = null;
byte[] fileInBytes = new byte[(int)file.length()];
try {
//convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(fileInBytes);
fileInputStream.close();
} catch (IOException e) {
System.out.println("Exception whilst compressing the file: " + e.getMessage());
}
ByteArrayOutputStream obj = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj);
gzip.write(fileInBytes);
gzip.close();
return obj.toByteArray();
}
UPDATE: Got past it, rather than .param, I should be using .header
It does not look like you are setting the content type when you are posting.
Try
this.mockMvc.perform(post("/test").header("site",site).param("customer",customer).
param("table", table).content(compress(file)).contentType("application/octet-stream").param("loadStatus",loadStatus)
.with(user("user"))).andExpect(status().isOk());
I'm trying to send aמ HTTP POST request in order to send contacts information to a Mail Exchange Server, using their API (creating a new "subscriber"). I'm using Java and java.util.HttpURLConnection.
When I try signing the connection, I'm getting a null reference exception. If I try signing the connection prior to adding the setRequestProperty headers, I'm getting an Invalid Signature response from the server.
Using a GET request with the same general procedure works - which means, as far as I understand, that my signing method (and key values etc.) is OK.
The service I'm trying to use has some kind of a "SDK" available, written in .NET. I didn't try to use it but I do believe it to work (they declare so).
I tried to replicate their procedure. Below you can find my code, follow by theirs:
private static HttpURLConnection createAndSendOAuthPostRequestWithParams () throws MalformedURLException, IOException, Exception {
String url = "http://apisdomain/v1.0/lists/354467/subscribers";
// Here I set up the values given by the provider (API's admin) which I removed from the example
String clientKey = "";
String clientSecret = "";
String userKey = "";
String userSecret = "";
String postData = "NAME=TestSubscriber&EMAIL=test#gmail.com
byte[] postBody = postData.getBytes("UTF-8");
URL apiUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("content-length", String.valueOf(postBody.length));
connection.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
//OAuth
OAuthConsumer consumer = new DefaultOAuthConsumer (clientKey, clientSecret);
//consumer.setAdditionalParameters(parameters);
consumer.setTokenWithSecret(userKey, userSecret);
HttpRequest httpReq = consumer.sign(connection); //Where the exception occurs
if (!postBody.toString().isEmpty()) {
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(postBody);
outputStream.flush();
}
}
return connection;
}
From thier SDK:
using System.Text;
namespace ResponderSDK
{
using OAuth;
using System;
using System.Collections.Generic;
using System.Net;
using System.IO;
class ResponderOAuth
{
/* Contains the last HTTP status code returned. */
public HttpStatusCode http_code;
/* Contains the last API call. */
public string url;
/* Set up the API root URL. */
public string host = "http://api.responder.co.il/v1.0/";
/* Set timeout default. */
public int timeout = 3000;
/* Set connect timeout. */
public int connect_timeout = 30;
/* Verify SSL Cert. */
public bool ssl_verifypeer = false;
/* Response format. */
public string format = "json";
/* Contains the last HTTP headers returned. */
public string http_info;
/* Set the useragent. */
public string useragent = "ResponderOAuth v0.1-beta";
/*debug info*/
public string headers_string;
public string base_string;
public string post_string;
/* Signature */
private OAuthSignatureMethod_HMAC_SHA1 signature;
/* OAuthConsumer */
private OAuthConsumer consumer;
/* Token */
private OAuthToken token;
public ResponderOAuth(string consumer_key, string consumer_secret, string oauth_token = null, string oauth_token_secret = null)
{
this.signature = new OAuthSignatureMethod_HMAC_SHA1();
this.consumer = new OAuthConsumer(consumer_key, consumer_secret);
if (!String.IsNullOrEmpty(oauth_token) && !String.IsNullOrEmpty(oauth_token_secret))
{
this.token = new OAuthToken(oauth_token, oauth_token_secret);
}
else
{
this.token = null;
}
}
public string http_request(string url, string method = "GET", ParametersArray parameters = null)
{
method = method.ToUpper();
if (url.LastIndexOf("https://") != 0 && url.LastIndexOf("http://") != 0)
{
url = String.Format("{0}{1}", this.host, url);
}
if (method.Equals("GET"))
parameters = null;
OAuthRequest request = OAuthRequest.from_consumer_and_token(this.consumer, this.token, method, url, parameters);
request.sign_request(this.signature, this.consumer, this.token);
this.base_string = request.base_string;
if (method.Equals("GET"))
return this.http(request.to_url(), "GET", request.to_header(), null);
else
return this.http(request.get_normalized_http_url(), method, request.to_header(), request.to_postdata());
}
private string http(string url, string method, WebHeaderCollection headers, string data = null)
{
List<string> new_http_info = new List<string>();
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
HttpWebRequest request = null;
if (!method.Equals("DELETE"))
request = (HttpWebRequest)WebRequest.Create(url);
else
{
if (!String.IsNullOrEmpty(data))
{
url = String.Format("{0}?{1}", url, data);
}
request = (HttpWebRequest)WebRequest.Create(url);
}
/* WebRequest settings */
((HttpWebRequest)request).ProtocolVersion = System.Net.HttpVersion.Version10;
((HttpWebRequest)request).UserAgent = this.useragent;
((HttpWebRequest)request).ContinueTimeout = this.connect_timeout;
((HttpWebRequest)request).Timeout = this.timeout;
((HttpWebRequest)request).Headers = headers;
((HttpWebRequest)request).UseDefaultCredentials = true;
((HttpWebRequest)request).PreAuthenticate = true;
((HttpWebRequest)request).Credentials = CredentialCache.DefaultCredentials;
this.headers_string = headers.ToString();
this.post_string = data;
byte[] dataByteArray = null;
if ((!String.IsNullOrEmpty(data) && method.Equals("POST")) || method.Equals("PUT"))
{
((HttpWebRequest)request).ContentType = "application/x-www-form-urlencoded";
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
dataByteArray = encoding.GetBytes(data);
((HttpWebRequest)request).ContentLength = dataByteArray.Length;
((HttpWebRequest)request).Expect = "";
}
switch (method)
{
case "POST":
((HttpWebRequest)request).Method = "POST";
if (!String.IsNullOrEmpty(data))
{
Stream dataPost = request.GetRequestStream();
dataPost.Write(dataByteArray, 0, dataByteArray.Length);
dataPost.Close();
}
break;
case "PUT":
((HttpWebRequest)request).Method = "PUT";
if (!String.IsNullOrEmpty(data))
{
Stream dataPost = request.GetRequestStream();
dataPost.Write(dataByteArray, 0, dataByteArray.Length);
dataPost.Close();
}
break;
case "DELETE":
((HttpWebRequest)request).Method = "DELETE";
break;
}
WebResponse response = request.GetResponse();
this.http_code = ((HttpWebResponse)response).StatusCode;
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
return reader.ReadToEnd();
}
}
}
If your input String format is json, you can change content-type to "application/json" and try signing in after adding the setRequestProperty headers.
How to write a integration test when I'm uploading a image to the server. I've already written a test following this question and it's answer but mine is not working properly. I used JSON to send the image and expected status OK. But I'm getting:
org.springframework.web.utill.NestedServletException:Request
Processing Failed;nested exception is java.lang.illigulArgument
or http status 400 or 415. I guess the meaning is same. Below I've given my test portion and controller class portion.
Test portion:
#Test
public void updateAccountImage() throws Exception{
Account updateAccount = new Account();
updateAccount.setPassword("test");
updateAccount.setNamefirst("test");
updateAccount.setNamelast("test");
updateAccount.setEmail("test");
updateAccount.setCity("test");
updateAccount.setCountry("test");
updateAccount.setAbout("test");
BufferedImage img;
img = ImageIO.read(new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\Penguins.jpg"));
WritableRaster raster = img .getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
byte[] testImage = data.getData();
updateAccount.setImage(testImage);
when(service.updateAccountImage(any(Account.class))).thenReturn(
updateAccount);
MockMultipartFile image = new MockMultipartFile("image", "", "application/json", "{\"image\": \"C:\\Users\\Public\\Pictures\\Sample Pictures\\Penguins.jpg\"}".getBytes());
mockMvc.perform(
MockMvcRequestBuilders.fileUpload("/accounts/test/updateImage")
.file(image))
.andDo(print())
.andExpect(status().isOk());
}
Controller portion:
#RequestMapping(value = "/accounts/{username}/updateImage", method = RequestMethod.POST)
public ResponseEntity<AccountResource> updateAccountImage(#PathVariable("username") String username,
#RequestParam(value="image", required = false) MultipartFile image) {
AccountResource resource =new AccountResource();
if (!image.isEmpty()) {
try {
resource.setImage(image.getBytes());
resource.setUsername(username);
} catch (IOException e) {
e.printStackTrace();
}
}
Account account = accountService.updateAccountImage(resource.toAccount());
if (account != null) {
AccountResource res = new AccountResourceAsm().toResource(account);
return new ResponseEntity<AccountResource>(res, HttpStatus.OK);
} else {
return new ResponseEntity<AccountResource>(HttpStatus.EXPECTATION_FAILED);
}
}
If I write my controller this way It shows IllegalArgument in Junit trace but no problem in console and no mock print as well. So, I replace Controller with this:
#RequestMapping(value = "/accounts/{username}/updateImage", method = RequestMethod.POST)
public ResponseEntity<AccountResource> updateAccountImage(#PathVariable("username") String username,
#RequestBody AccountResource resource) {
resource.setUsername(username);
Account account = accountService.updateAccountImage(resource.toAccount());
if (account != null) {
AccountResource res = new AccountResourceAsm().toResource(account);
return new ResponseEntity<AccountResource>(res, HttpStatus.OK);
} else {
return new ResponseEntity<AccountResource>(HttpStatus.EXPECTATION_FAILED);
}
}
Than I have this output in console:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /accounts/test/updateImage
Parameters = {}
Headers = {Content-Type=[multipart/form-data;boundary=265001916915724]}
Handler:
Type = web.rest.mvc.AccountController
Method = public org.springframework.http.ResponseEntity<web.rest.resources.AccountResource> web.rest.mvc.AccountController.updateAccountImage(java.lang.String,web.rest.resources.AccountResource)
Async:
Was async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.HttpMediaTypeNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
MockHttpServletResponse:
Status = 415
Error message = null
Headers = {Accept=[application/octet-stream, text/plain;charset=ISO-8859-1, application/xml, text/xml, application/x-www-form-urlencoded, application/*+xml, multipart/form-data, application/json;charset=UTF-8, application/*+json;charset=UTF-8, */*]}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Now, I need to know how to solve this problem or should I take another approach and what is that.
The problem was because controller class is meant to receive multipart/form-data,but sent JSON data. There is another problem in this code. The controller returns the resource that having image inside. That causing processing failed. Right code is given below:
#test portion
Account updateAccount = new Account();
updateAccount.setPassword("test");
updateAccount.setNamefirst("test");
updateAccount.setNamelast("test");
updateAccount.setEmail("test");
updateAccount.setCity("test");
updateAccount.setCountry("test");
updateAccount.setAbout("test");
BufferedImage img;
img = ImageIO.read(new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\Penguins.jpg"));
WritableRaster raster = img .getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
byte[] testImage = data.getData();
updateAccount.setImage(testImage);
FileInputStream fis = new FileInputStream("C:\\Users\\Public\\Pictures\\Sample Pictures\\Penguins.jpg");
MockMultipartFile image = new MockMultipartFile("image", fis);
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "265001916915724");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
when(service.updateAccountImage(any(Account.class))).thenReturn(
updateAccount);
mockMvc.perform(
MockMvcRequestBuilders.fileUpload("/accounts/test/updateImage")
.file(image)
.contentType(mediaType))
.andDo(print())
.andExpect(status().isOk());
Controller Portion:
#RequestMapping(value = "/{username}/updateImage", method = RequestMethod.POST)
public #ResponseBody
ResponseEntity<AccountResource> updateAccountImage(#PathVariable("username") String username,
#RequestParam("image") final MultipartFile file)throws IOException {
AccountResource resource =new AccountResource();
resource.setImage(file.getBytes());
resource.setUsername(username);
Account account = accountService.updateAccountImage(resource.toAccount());
if (account != null) {
AccountResource res = new AccountResourceAsm().toResource(account);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity<AccountResource>(res,headers, HttpStatus.OK);
} else {
return new ResponseEntity<AccountResource>(HttpStatus.NO_CONTENT);
}
}
I can test this using apache.commons.httpClient library like shown below
#Test
public void testUpload() {
int statusCode = 0;
String methodResult = null;
String endpoint = SERVICE_HOST + "/upload/photo";
PostMethod post = new PostMethod(endpoint);
File file = new File("/home/me/Desktop/someFolder/image.jpg");
FileRequestEntity entity = new FileRequestEntity(file, "multipart/form-data");
post.setRequestEntity(entity);
try {
httpClient.executeMethod(post);
methodResult = post.getResponseBodyAsString();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
statusCode = post.getStatusCode();
post.releaseConnection();
//...
}