Question

I have a need to pull images repetitively from a .NET ASHX handler that follows the form http://domain.com/handler.ashx?id=013505 where the ID identifies the person whose image the handler should serve. I have to do this in a PeopleSoft application, so I am limited to what is delivered in PeopleCode for the most part, but can use a good amount of Java as well (though syntactically, it wouldn't make a lot of sense to a pure Java developer). What I've been able to do thus far

  • Open a connection to the URL using the URL class and the URLConnection class's openConnection method, to ultimately end up with an InputStream object.
  • I then attempt to use the ImageIO class to retrieve a BufferedImage object using the read method and passing in the aforementioned InputStream object
  • At this point, the BufferedImage object always returns "null". What seems to be getting returned is not an image, but just a brief blurb of HTML.
  • If I use a direct path to a URL (no query string, eg http://domain.com/image.jpg) my methodology works just fine and I'm able to work with the BufferedImage object that is returned.
  • I've tried explicitly setting the User-Agent string on the URLConnection with the setRequestProperty method as another post here had suggested, but to no avail.

I'll be happy to post the code I'm using if anyone would find it helpful, but as I said, it's a "PeopleCode-ized" use of these Java classes, so it may not be meaningful to many. I'm really just looking for some general advice in Java of what else might be going wrong; I can translate it from there to try things in PeopleCode.

Was it helpful?

Solution

Just for prosperity's sake, since this will live on in perpetuity on "teh interwebs" here was the ultimate solution to my problem:

First off, the reason I was getting back the "blurb of HTML" I referenced was because the URL I was pointing to was doing a redirect to another server.

Once I got that figured out and pointed to the "real" server, I began receiving SSL Certificate trust errors. In this case, the server had an internal self-signed certificate. I tried simply installing that certificate on my PeopleSoft web server, and in PeopleSoft's Digitial Certificates library, but to no avail. I then moved on to plan B: forcing my PeopleCode/Java hybrid to use the Certificate itself.

For the most part, this post, helped me figure out what I needed to do. In general, these are the steps I took:

  • Create a CertificateFactory based on the PEM-formated certificate string
  • Get a Certificate object from the Certificate factory (generateCertificate method)
  • Create a Keystore object using the Certificate (setCertificateEntry method).
  • Create a TrustManagerFactory object, initiatilzed with the Keystore object (init method, passing in Keystore object)
  • Create an SSLContext object, initialized with the TrustManagerFactory object (init method, passing in TrustManagerFactory.getTrustManagers())
  • Get an SSLSocketFactory object from the SSLContext object (getSocketFactory method)
  • Create URL object, pointing to the ASHX handler
  • Get the URLConnection object from the URL object (openConnection method)
  • Cast that URLConnection object to an HttpsURLConnection object. This may seem mundane, but to do it in PeopleCode it took creating a custom cast class and static method, hence why I am referncing it here (credit to Jim's PeopleSoft Journal for that bit).
  • Get the image InputStream object from the HttpsURLConnection (getInputStream method)
  • Create a BufferedImage object from the InputStream using the ImageIO class's read method (passing in the InputStream)
  • Write that BufferedImage object to a File object using the ImageIO write method.
  • Write that file into PeopleSoft's EMPL_PHOTO record, following the general steps found in this blog post.

Hopefully someone in the future will find this helpful. Here's the full PeopleCode for reference (note, that this is just test code I tied to a button a page's FieldChange event):

Local JavaObject &joCertString, &joUrl, &joUrlConnection, &joInputStream, &joImageIO, &joBufferedImage, &joFile;
Local JavaObject &joCertificateFactoryClass, &joCertificateFactory, &joCertInputStream, &joCertificate;
Local JavaObject &joKeystoreClass, &joKeystore, &joTrustManagerFactoryClass, &joTrustManagerFactory;
Local JavaObject &joSSLContextClass, &joSSLContext, &joSSLFactory, &joCastObjectClass;
Local any &anyFileData;
Local Record &recTest;
Local string &sPhotosCert;
Local number &nPutResult;

/*Setup CertificateFactory*/
&sPhotosCert = GetHTMLText(HTML.PHOTOS_CERT);
&joCertString = CreateJavaObject("java.lang.String", &sPhotosCert);
&joCertificateFactoryClass = GetJavaClass("java.security.cert.CertificateFactory");
&joCertificateFactory = &joCertificateFactoryClass.getInstance("X.509");
&joCertInputStream = CreateJavaObject("java.io.ByteArrayInputStream", &joCertString.getBytes("UTF-8"));
&joCertificate = &joCertificateFactory.generateCertificate(&joCertInputStream);

/*Create Keystore*/
&joKeystoreClass = GetJavaClass("java.security.KeyStore");
&joKeystore = &joKeystoreClass.getInstance("JKS");
&joKeystore.load( Null, Null);
&joKeystore.setCertificateEntry("photos", &joCertificate);

/*Create TrustManagerFactory*/
&joTrustManagerFactoryClass = GetJavaClass("javax.net.ssl.TrustManagerFactory");
&joTrustManagerFactory = &joTrustManagerFactoryClass.getInstance(&joTrustManagerFactoryClass.getDefaultAlgorithm());
&joTrustManagerFactory.init(&joKeystore);

/*Create SSLContext and get SSLSocketFactory*/
&joSSLContextClass = GetJavaClass("javax.net.ssl.SSLContext");
&joSSLContext = &joSSLContextClass.getInstance("TLS");
&joSSLContext.init( Null, &joTrustManagerFactory.getTrustManagers(), Null);
&joSSLFactory = &joSSLContext.getSocketFactory();

/*Create URL*/
&joUrl = CreateJavaObject("java.net.URL", "https://domain.com/handler.ashx?id=123456");

/*Get URLConnection*/
&joUrlConnection = &joUrl.openConnection();

/*Cast to HttpsURLConnection*/
&joCastObjectClass = GetJavaClass("com.domain.CastObject");
&joUrlConnection = &joCastObjectClass.objectToHttpsURLConnection(&joUrlConnection);

/*Set connection properties*/
&joUrlConnection.setSSLSocketFactory(&joSSLFactory);
&joUrlConnection.setRequestMethod("GET");

/*Get InputStream*/
&joInputStream = GetJavaClass("java.io.InputStream");
&joInputStream = &joUrlConnection.getInputStream();

/*Get Image From Stream*/
&joImageIO = GetJavaClass("javax.imageio.ImageIO");
&joBufferedImage = CreateJavaObject("java.awt.image.BufferedImage", 1, 1, 1);
&joBufferedImage = &joImageIO.read(&joInputStream);

/*Write Image to File*/
&joFile = CreateJavaObject("java.io.File", "/temp/URLImage2.jpg");
&joImageIO.write(&joBufferedImage, "jpg", &joFile);

/*Put the File into a PS record so we can get a BLOB of it*/
&nPutResult = PutAttachment("record://PSFILE_ATTDET", "013505.jpg", "/temp/URLImage2.jpg");

/*Grab that BLOB*/
SQLExec("SELECT FILE_DATA FROM PSFILE_ATTDET WHERE ATTACHSYSFILENAME = :1 AND VERSION = 1", "013505.jpg", &anyFileData);

/*Clean up the temp row we inserted*/
SQLExec("DELETE FROM PSFILE_ATTDET WHERE ATTACHSYSFILENAME = :1 AND VERSION = 1", "013505.jpg");

/*Setup an employee photo record*/
&recTest = CreateRecord(Record.EMPL_PHOTO);
&recTest.EMPLID.Value = "013505";
&recTest.PSIMAGEVER.Value = (Days365(Date3(1999, 12, 31), %Date) * 86400) + (%Time - Time3(0, 0, 0));
&recTest.EMPLOYEE_PHOTO.Value = &anyFileData;

/*Insert/Update the employee photo record*/
&recTest.Insert();
&recTest.Update();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top