How to consume image upload data as byte[] using Spring MVC 3 - spring-mvc

I need write the image data in a particular directory on the server side but I am getting a null for the raw byte[] image upload data that I am trying to send from an html form and jquery ajaxuploader plugin from here.
Following is the snippet from the controller I am using to handle raw bytes of image being uploaded:
#RequestMapping(value = "uploadImage", method = RequestMethod.POST)
public void uploadImage(byte[] uploadData, Writer writer, HttpServletRequest request) throws IOException, JSONException {
//uploadData is turning out to be null
//..
}
#InitBinder
protected void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(byte[].class,
new ByteArrayMultipartFileEditor());
}
I have got the following configured in the spring configuration file for handling uploads:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
I am using Spring MVC 3. Could someone guide me on how to send raw bytes of upload data?
Thanks.

First, if you're form is uploading an image, make sure your content type is "multipart/form-data". You might want to change your RequestMapping as follows:
#RequestMapping(value = "uploadImage", method = RequestMethod.POST, headers={"content-type=multipart/form-data"})
Also, I'd suggest using CommonsMultipartFile to handle the upload. Change your function signature as follows, where "fieldName" is the name of the input field in your form:
public void uploadImage(byte[] uploadData, Writer writer, HttpServletRequest request, #RequestParam("fieldName") CommonsMultipartFile file)
Then you can get the raw bytes as follows:
file.getBytes()
Make sure you include the commons-fileupload dependency for CommonsMultipartFile.
I'm using spring3 + jquery ajaxform and this works like a charm. Hope this helps!

Following is the JavaScript and HTML code I used on the client side that got things working:
JavaScript:
function createUploader(){
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: 'uploadImage',
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'],
debug: true,
onSubmit: function(id, fileName){
console.log("id - " + id + ", fileName - " + fileName);
},
onComplete: function(id, fileName, responseJSON) {
console.log("responseJSON - " + responseJSON);
}
});
}
window.onload = createUploader;
HTML:
<div id="file-uploader" >
<noscript>
<p>Please enable JavaScript to upload your property location images</p>
</noscript>
</div>
Controller:
#Controller
public class FranchiseeLocationImageController {
private static final Log logger = LogFactory.getLog(FranchiseeLocationImageController.class);
#Autowired
private ServletContext servletContext;
#Autowired
private FranchiseeLocationImageService franchiseeLocationImageService;
#RequestMapping(value = "uploadImage", method = RequestMethod.POST)
public void uploadImage(byte[] qqfile, Writer writer, #RequestParam("qqfile") String img, HttpServletRequest request, HttpServletResponse response) throws IOException, JSONException{
FranchiseeLocationImage image = null;
PrintWriter pr = null;
InputStream is = null;
File file = null;
FileOutputStream fos = null;
String filename = request.getHeader("X-File-Name");
String imageId = FilenameUtils.removeExtension(img);
String imageFormat = franchiseeLocationImageService.getImageFormat();
String outputDir = servletContext.getRealPath("") + File.separator + franchiseeLocationImageService.getImagesDirectory() + File.separator;
File baseDirectory = null;
File output = null;
String path = FilenameUtils.removeExtension(img) + "." + imageFormat;
File outputDirectory = null;
HttpSession session = request.getSession();
/*
HttpSession session = request.getSession(false);
if(session == null) {
session = request.getSession();
}
*/
List<String> franchiseeLocationImages = (List<String>) session.getAttribute("franchiseeLocationImages");
if(franchiseeLocationImages == null) {
franchiseeLocationImages = new ArrayList<String>();
}
logger.debug( "filename - " + filename + " | img - " + img + " | img name - " + FilenameUtils.removeExtension(img) + " | img format - " + FilenameUtils.getExtension(img) + " | uploadData - " + qqfile + " | imageFormat - " + imageFormat);
/**
* Reading the image being uploaded and writing it to images/franchiseeLocation folder ["qqfile" is used instead of "X-File-Name" as "X-File-Name" gives encoded HTML name with "%20" for " "]
*/
try {
pr = response.getWriter();
is = request.getInputStream();
/*
baseDirectory = new File(outputDir);
baseDirectory.mkdirs();
file = new File(outputDir, FilenameUtils.removeExtension(img) + "." + imageFormat);
fos = new FileOutputStream(file);
int copiedNum = IOUtils.copy(is, fos);
*/
outputDirectory = new File(outputDir);
outputDirectory.mkdirs();
output = new File(outputDirectory, path);
BufferedImage sourceImage = ImageIO.read(is);
boolean written = ImageIO.write(sourceImage, imageFormat, output);
franchiseeLocationImages.add(img);
session.setAttribute("franchiseeLocationImages", franchiseeLocationImages);
logger.debug("franchiseeLocationImages - " + franchiseeLocationImages);
logger.debug("outputDirectory - " + outputDirectory + " | output - " + output + " | sourceImage - " + sourceImage + " | is - " + is + " | file - " + file + " |fos - " + fos + " | copiedNum - " + "copiedNum" + " | baseDirectory - " + baseDirectory + " | sourceImage - " + sourceImage + " | written - " + written);
/*
image = franchiseeLocationImageService.processProductImage(qqfile, imageId);
JSONObject json = new JSONObject();
json.put("path", image.getPath());
json.put("id", image.getId());
writer.write(json.toString());
*/
pr.print("{success: true}");
} finally {
writer.close();
/*
try {
fos.close();
is.close();
} catch (IOException ignored) {
}
*/
pr.flush();
pr.close();
}
}
#InitBinder
protected void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(byte[].class,
new ByteArrayMultipartFileEditor());
}
private static String html2text(String html) {
return Jsoup.parse(html).text();
}
}

Related

ProcessBuilder&Runtime exec could not find or load main class in Spring Project

I want to compile a java file and exec its class in another class ( ← This class is a #service of a Spring MVC project ).
The service code is:
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile the java file
String[] cmd = {"javac", "P" + id + ".java"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
// exec the class file
String[] execmd = {"java", "P" + pz_id};
ProcessBuilder epb = new ProcessBuilder(execmd);
epb.directory(new File(fd));
p = epb.start();
// get normal output
BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
String ptmp = pin.readLine();
while (ptmp != null) {
pout = pout == null ? ptmp + '\n' : pout + ptmp + '\n';
ptmp = pin.readLine();
}
// get error output
pin = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String wout = null;
ptmp = pin.readLine();
while (ptmp != null) {
wout = wout == null ? ptmp + '\n' : wout + ptmp + '\n';
ptmp = pin.readLine();
}
// print output
System.out.println(pout);
System.out.println(wout);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null; // for test
}
When this Service is invoked, I always get a Error: Could not find or load main class: P[id]
I cd theFilePath, the P[id].class file is existing.
And I can run java P[id] successfully in theFilePath.
And I try to replace ProcessBuilder with Runtime, like:
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile the java file
String[] cmd = {"javac", "P" + id + ".java"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
// exec the class file
String execmd = "java", fd + "/P" + pz_id;
p = Runtime.getRuntime().exec(execmd);
// get normal output
BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
String ptmp = pin.readLine();
while (ptmp != null) {
pout = pout == null ? ptmp + '\n' : pout + ptmp + '\n';
ptmp = pin.readLine();
}
// get error output
pin = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String wout = null;
ptmp = pin.readLine();
while (ptmp != null) {
wout = wout == null ? ptmp + '\n' : wout + ptmp + '\n';
ptmp = pin.readLine();
}
// print output
System.out.println(pout);
System.out.println(wout);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null; // for test
}
I get the same Error again T^T
IDE is sts-bundle, server is tomcat8
I know what is wrong here.
pb.start(); does not mean the command of pb will be executed immediately.
So if I set pb of command javac hello.java; set epb of command java hello
And I call pb.start(); epb.start(); continuously, I will get an Error: could not find or load main class: hello, because when I exec epb.start(); The former command(pb.start) may have not been executed!
I got 2 solution:
First: set a finally field and exec epb.start() in this field, like:
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile the java file
String[] cmd = {"javac", "P" + id + ".java"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// exec the class file
String[] execmd = {"java", "P" + pz_id};
ProcessBuilder epb = new ProcessBuilder(execmd);
epb.directory(new File(fd));
Process p = epb.start();
}
return null; // for test
}
Second: a trick of bash
#Service
public class MRServiceImp implements MRService {
#Override
public String submitMR(int id, String fd) {
try {
// compile & exec the java file
String[] cmd = {"/bin/bash"};
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(fd));
Process p = pb.start();
BufferedWriter pbw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
pbw.write("javac *.java;java P" + pz_id+";exit;");
pbw.newLine();
pbw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null; // for test
}
I use the second one.

Handle file name duplication when creating files in alfresco

I have a Java-backed webscript in repo tier that creates files (with given name) in a given folder in Alfresco.
To handle the file name duplication issue I wrote this code:
NodeRef node = null;
try {
node = createNode(fullName, folderNodeRefId);
} catch (DuplicateChildNodeNameException e) {
System.out.println("Catched");
boolean done = false;
for (int i = 1; !done; i++) {
String newName = filename + "_" + i + "." + fileFormat;
System.out.println("Duplicate Name. Trying: " + newName);
try {
node = createNode(newName, folderNodeRefId);
done = true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
System.out.println("Done");
ContentWriter writer = serviceRegistry.getContentService().getWriter(node, ContentModel.PROP_CONTENT, true);
writer.setMimetype(getFileFormatMimetype(fileFormat));
writer.putContent(inputStream);
writer.guessEncoding();
and
private NodeRef createNode(String filename, String folderNodeRefId)
throws InvalidNodeRefException, InvalidTypeException, InvalidQNameException {
System.out.println("In " + filename);
NodeRef folderNodeRef = new NodeRef(folderNodeRefId);
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, filename);
return serviceRegistry.getNodeService()
.createNode(folderNodeRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, filename), ContentModel.TYPE_CONTENT,
props)
.getChildRef();
}
The codes work very fine if there is no file name duplication (a new name). But it does nothing when there is a duplication, although it executes without any errors! When I test it it doesn't throw any exceptions but no file is created either!
Any hints about the cause of that?
Thanks,
I tested this code , It's working fine
#Test
public void createNode() {
AuthenticationUtil.setFullyAuthenticatedUser(ADMIN_USER_NAME);
NodeRef node = null;
String fileFormat = "txt";
String filename = "test";
NodeRef folderNodeRef = getCompanyHome();
//Create first node
node = createNode(filename, folderNodeRef);
try {
node = createNode(filename, folderNodeRef);
} catch (DuplicateChildNodeNameException e) {
System.out.println("Catched");
boolean done = false;
for (int i = 1; !done; i++) {
String newName = filename + "_" + i + "." + fileFormat;
System.out.println("Duplicate Name. Trying: " + newName);
try {
node = createNode(newName, folderNodeRef);
done = true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
System.out.println("Done");
}
private NodeRef getCompanyHome() {
return nodeLocatorService.getNode("companyhome", null, null);
}
private NodeRef createNode(String filename, NodeRef folderNodeRef) throws InvalidNodeRefException, InvalidTypeException, InvalidQNameException {
System.out.println("In " + filename);
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, filename);
return serviceRegistry.getNodeService().createNode(folderNodeRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, filename), ContentModel.TYPE_CONTENT,props).getChildRef();
}

how to upload photo to sql using json wcf

I am creating WCF for an iphone app. i want to know how to upload photo to the sql using json wcf any idea?this is the process how to connect it to the sql?
public class TestService : ITestService
{
[WebInvoke(Method = "POST", UriTemplate = "UploadFile?fileName={fileName}")]
public string UploadFile(string fileName, Stream fileContents)
{
//save file
string absFileName = "";
try
{
absFileName = string.Format("{0}\\FileUpload\\{1}"
, AppDomain.CurrentDomain.BaseDirectory
, Guid.NewGuid().ToString().Substring(0,6) + ".jpg");
// string fld = #"h:\root\home\amrmk185-001\www\publish\WCFService\FileUpload\" + fileName;
//System.IO.File.Create(absFileName);
using (FileStream fs = new FileStream(absFileName, FileMode.Create))
{
fileContents.CopyTo(fs);
fileContents.Close();
}
return "Upload OK";
}
catch(Exception ex)
{
return "FAIL ==> " + ex.Message + " " + absFileName;
}
}

asp.net upload control is not working in ipad

The asp.net upload control is uploading the file for first time in Ipad but not after that and not even showing any error
The code is as below
protected void UploadThisFile(FileUpload upload)
{
try
{
string folderpath = ConfigurationManager.AppSettings["BTCommDynamic"].ToString() + ConfigurationManager.AppSettings["Attachments"].ToString();
Guid fileguid = Guid.NewGuid();
string filename = fileguid + upload.FileName;
if (upload.HasFile && dtFiles != null)
{
DataRow drFileRow = dtFiles.NewRow();
drFileRow["FileName"] = upload.FileName;
string theFileName = Path.Combine(Server.MapPath(folderpath), filename);
string theFileName1 = Path.Combine(folderpath, filename);
//string theFileName = folderpath;
//to save the file in specified path
upload.SaveAs(theFileName);
drFileRow["FilePath"] = theFileName1;
double Filesize = (upload.FileContent.Length);
if (Filesize > 1024)
{
drFileRow["FileSize"] = (upload.FileContent.Length / 1024).ToString() + " KB";
}
else
{
drFileRow["FileSize"] = (upload.FileContent.Length).ToString() + " Bytes";
}
dtFiles.Rows.Add(drFileRow);
gvAttachment.DataSource = dtFiles;
gvAttachment.DataBind();
}
}
catch (Exception ex)
{
string message = Utility.GetExceptionMessage(ex.GetType().ToString(), ex.Message);
Display_Message(message);
}
}
Do you use firebug? There might be an error on a client side that prevents the work of your functionality.
Do you have any logic on your client side? Some kinda jquery/ajax calls?

File created insted of Folder in Alfresco

I am trying to create a folder in Alfresco using XMSI below is the code i am using .
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
String host = "127.0.0.1";
int port = 9080;
String username = "admin";
String password = "admin";
String parentFolder = "Company%20Home";
String folderName = "sales3";
String description = "sales space3";
RulesRequest request = new RulesRequest();
//request.setRemediationProfileObj(remediationProfile);
Gson gs = new Gson();
String json = gs.toJson(request);
DefaultHttpClient client = new DefaultHttpClient();
RestClient rstClnt = new RestClient();
String ticket = rstClnt.restClientPost(json, "http://127.0.0.10:9080/alfresco/service/api/login?u=admin&pw=admin", client);
//String url = "http://" + host + ":" + port + "/alfresco/service/api/path/workspace/SpacesStore/" + parentFolder + "/children";
String url = "http://localhost:9080/alfresco/service/cmis/s/workspace:SpacesStore/i/078b05c6-14bd-439c-a1ae-db032c5d98fc/children?alf_ticket="+ticket;
String contentType = "application/atom+xml;type=entry";
String xml =
"<?xml version='1.0' encoding='utf-8'?>\n" +
"<entry xmlns='http://www.w3.org/2005/Atom' xmlns:cmis='http://www.cmis.org/2008/05'>\n" +
"<title>" + folderName + "</title>\n" +
"<summary>" + description + "</summary>\n" +
"<cmis:object>\n"+
"<cmis:properties>\n" +
"<cmis:propertyString cmis:name='cmis:objectTypeId'>\n" +
"<cmis:value>cmis:folder</cmis:value>\n" +
"</cmis:propertyString>\n" +
"</cmis:properties>\n" +
"</cmis:object>\n" +
"</entry>\n";
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(host, port),
new UsernamePasswordCredentials(username, password));
HttpPost httppost = new HttpPost(url);
httppost.setHeader("Content-type", contentType);
StringEntity requestEntity = new StringEntity(xml, "UTF-8");
httppost.setEntity(requestEntity);
System.out.println("executing request" + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content type: " + entity.getContentType());
long contentLength = entity.getContentLength();
System.out.println("Response content length: "
+ entity.getContentLength());
if (contentLength > 0) {
byte [] b = new byte[(int) contentLength];
entity.getContent().read(b);
System.out.println("Response content: " + new String(b));
}
entity.writeTo(System.out);
}
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
long end = System.currentTimeMillis();
System.out.println("Time spend: " + (end-start) + "ms");
}
Instead of creating a folder it is creating a file of size 0.
Thanks
Garvit
Your property is of the wrong type. You are incorrectly using cmis:propertyString instead of cmis:propertyId Try the following
<cmis:propertyId propertyDefinitionId="cmis:objectTypeId">
<cmis:value>cmis:folder</cmis:value>
</cmis:propertyId>
As #Gagravarr says, problems like this are easily avoided if you can use well-known client libraries. If you are constructing the HTTP requests yourself you'd better have a good reason for that.

Resources