Can I pass an object using xmlrpc in java - java

I want to pass an object using xmlrpc as this is the only possible way it seems that I can pass an Integer and a String to a method on the server. Is it possible to do this using an object? If not is there some other way of doing it?
I have attempted to do it but am getting this error:
JavaClient: XML-RPC Consumer Fault #java.io.IOException: unsupported
Java type: class Client.Article
This is the code on the client side:
public void addHash()
{
try {
addAuthorName = txtAddAuthorName.getText();
int addArticleNumber = Integer.parseInt(txtAddArticleNumber.getText());
newArticle = new Article(addAuthorName, addArticleNumber);
Vector<Object> addArticleArglist = new Vector<Object>();
addArticleArglist.addElement(newArticle);
System.out.println(newArticle);
// make the call
String callit = ("GetSize.addHash");
articleID = (Integer) client.execute(callit, addArticleArglist);
} // Use XmlRpcException errors
catch (XmlRpcException exception) {
System.err.println("JavaClient: XML-RPC Consumer Fault #"
+ Integer.toString(exception.code) + ": "
+ exception.getCause() + "" + exception.toString());
} catch (Exception exception) {
System.err.println("JavaClient: XML-RPC Consumer Fault #" + exception.toString());
}
}
This is the code on the server side however by using System.out.println I have discovered that for whatever reason none of the code within this method is being executed:
public void addHash(Article newArticle)
{
theHashtable.addHash(newArticle.getArticleName(), newArticle.getAuthorID());
}

Assuming you are using ws-xmlrpc the documentation states the following:
DOM nodes, or JAXB objects, can be transmitted. So are objects implementing the java.io.Serializable interface.
So by declaring your object serializable you would be able to transmit it. Depending what you want to do it might be a good idea to take a good look at jaxb.
See http://ws.apache.org/xmlrpc/ for more info.

Related

Create correct HL7 message containing RXO segment in Java

I am trying to create an HL7 message in Java and then print the resulting message. I am faking basic patient information and then adding the Drug Prescription information. Then, I want to print the complete message but I wasn't able to use the API correctly. I am new at using HL7, so I know I'm probably missing some required segments and even using the wrong ones, can you please help? This is my current code:
public RXO runDrugPrescriptionEvent(CMSGeneric cmsgen) {
CMSDrugPrescriptionEvent cmsic = (CMSDrugPrescriptionEvent) cmsgen;
ADT_A28 adt23 = new ADT_A28();
try {
adt23.initQuickstart("ADT", "A08", cmsic.getPDE_EVENT_ID());
// We set the sex identity (male or female)
if (cmsic.getBENE_SEX_IDENT_CD() == 1) {
adt23.getPID().getSex().setValue("Male");
}
else {
adt23.getPID().getSex().setValue("Female");
}
// We set a fake name and family name
adt23.getPID().insertPatientName(0).getGivenName().setValue("CMS Name " + MainTest.NEXT_PATIENT_ID);
adt23.getPID().insertPatientName(0).getFamilyName().setValue("CMS Family name " + MainTest.NEXT_PATIENT_ID);
MainTest.NEXT_PATIENT_ID++;
RXO rxo = new RXO(adt23, new DefaultModelClassFactory());
rxo.getRxo1_RequestedGiveCode().getCe1_Identifier().setValue("" + cmsic.getPDE_DRUG_CD());
rxo.getRxo18_RequestedGiveStrength().setValue("" + cmsic.getPDE_DRUG_STR_CD());
rxo.getRxo19_RequestedGiveStrengthUnits().getCe1_Identifier().setValue("" + cmsic.getPDE_DRUG_STR_UNITS());
rxo.getRxo5_RequestedDosageForm().getCe1_Identifier().setValue("" + cmsic.getPDE_DRUG_DOSE_CD());
rxo.getRxo11_RequestedDispenseAmount().setValue("" + cmsic.getPDE_DRUG_QTY_DIS());
HapiContext context = new DefaultHapiContext();
Parser parser = context.getPipeParser();
String encodedMessage = adt23.getParser().encode(rxo.getMessage());
logger.debug("Printing Message:");
logger.debug(encodedMessage);
return rxo;
} catch (IOException e) {
System.out.println("IOException creating HL7 message. " + e.getMessage());
e.printStackTrace();
} catch (HL7Exception e) {
System.out.println("HL7Exception creating HL7 message. " + e.getMessage());
e.printStackTrace();
}
return null;
}
With this code, the logger prints the following message:
MSH|^~\&|||||20160331101349.8+0100||ADT^A08|110001|PDE-00001E6FADAD3F57|2.3
PID|||||CMS Family name 100~^CMS Name 100|||Female
But I was expecting to see the RXO segment as well. How can I achieve that?
I found that changing the message type from ADT_A28 to ORP_O10 would let me have all the fields I need, as ADT_A28 wasn't the appropriate message for the kind of information I needed. There's a complete example on how to set a great amount of segments in this type of message here. Then, I was able to print the complete message using the PipeParser:
HapiContext context = new DefaultHapiContext();
Parser parser = context.getPipeParser();
String encodedMessage = parser.encode(msg);
logger.debug("Printing EREncoded Message:");
logger.debug(encodedMessage);

Getting html Email Content in JavaMail

I've made an E- Mail Client for my Android- Phone using the JavaMail API. I dont knoq how to get the E- Mail Content if it's a html- Mail. I'm using the following Code to get the Content:
public void printMessage(int messageNo) throws Exception {
Log.i("MsgNo", "Getting message number: " + messageNo);
Message m = null;
try {
m = folder.getMessage(messageNo);
dumpPart(m);
} catch (IndexOutOfBoundsException iex) {
Log.i("Out of Range","Message number out of range");
}
}
public static void dumpPart(Part p) throws Exception {
if (p instanceof Message)
dumpEnvelope((Message)p);
Object content = p.getContent();
Log.i("dumpPart",(String) content);
String ct = p.getContentType();
try {
pr("CONTENT-TYPE: " + (new ContentType(ct)).toString());
Log.i("MsgNo", "Content Type");
} catch (ParseException pex) {
pr("BAD CONTENT-TYPE: " + ct);
Log.i("MsgNo", "Bad Content Type");
}
//* Using isMimeType to determine the content type avoids
// * fetching the actual content data until we need it.
if (p.isMimeType("text/plain")) {
pr("This is plain text");
pr("---------------------------");
Log.i("Text", (String)p.getContent());
} else {
Log.i("MsgNo", "Just a Separator");
// just a separator
pr("---------------------------");
}
}
In the Logcat, i get the return value of dumpenvelope((Message)p); , but after that nothing.
Does anybody know what to do?
Is any exception thrown?
Did you enable debugging and examine the protocol trace to see what might have failed?
Are you using IMAP?
It looks like your program was created out of pieces of the JavaMail sample program called msgshow.java, did you find the complete original sample program?
This JavaMail FAQ entry might help as well.

How can I create a node recursively using zookeeper client library on Java?

I know this question has been already asked and answered for a zookeeper using python. The answer was good, however, I want something more related with the code. I've already implemented a method to create a node, but I want to do it recursively. The structure for my nodes will be like this:
ZOOKEEPER
WEB SERVER
SERVER1
SERVER2
MODULE CONNECTED
DATABASE MODULE
COMPUTER1
COMPUTER2
SERVICE MODULE
COMPUTER3
SEARCH MODULE
COMPUTER4
I have something like:
Zookeeper zk = new Zookeeper(...);
public void createNodeRecursively(String type) {
final String node = "/" + type + "/" + info.getIP() + ":" + info.getPort(); // Correct line
if (zk.exists("/" + type, null) == null) {
Object ctx = new Object();
StringCallback cb = new StringCallback() {
public void processResult(int rc, String path,
Object ctx, String name) {
if (name.equals("/" + type))// just in case
try {
zk.create(node, info.getBytes(),
Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
} catch (Exception e) {
e.printStackTrace();
}
}
};
zk.create("/" + type, info.getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT, cb, ctx);
} else
zk.create(node, info.getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL);
}
}
As you can see I am using zk.create many times, so I want to make the method recursive in order to gain performance and have a better code, but I don't know how to start, I'll be very grateful if somebody can help me with this. Thank you very much in advance.
Zookeeper has useful properties:
Total order of (write) requests
Its asynchronous nature.
You can put on use that.
Simply issue whole tree as a bunch of asynchronous requests in correct order and then wait, until all of them successfully execute. Of course, you can ignore 'NodeExists' exceptions (but it is not good, due of the fact, that such errors will be written to logs).
I managed to achieve a better performance:
public void createNode(NodePath nodePath, NodeData nodeData, NodeRights nodeRights, NodeCreationHandler nodeCreationHandler) throws KeeperException, InterruptedException, ZookeeperCreationException {
if (zk == null) {
throw new ZookeeperCreationException("The zookeeper client has not been instanced.");
}
String targetPath = nodePath.getFullNodePath();
targetPath = targetPath.substring(1, targetPath.length());
byte[] serializedData = nodeData.serialize(new Object());
String[] array = targetPath.split(ICoordinationConstants.BASE_ROOT_SPTR);
String acum="";
for (int i = 0; i < array.length-1; i++) {
acum+=(ICoordinationConstants.BASE_ROOT_SPTR+array[i]);
if (zk.exists(acum, null) == null) {
zk.create(acum, serializedData, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
zk.create(acum+ICoordinationConstants.BASE_ROOT_SPTR+array[array.length-1], serializedData, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
}

Writing two types of message to a channel with Netty 4.x

With Netty's new 4.x API, there have been some changes (some big some small). I have migrated an old server core of mine to work with the new API, but I cannot figure out a way to solve this problem. In 3.x, I could use
MessageEvent e
This allowed me to cast e to the type I needed (in this case, ServerMessage and String, as those were the two types used for server->client messages).
When using 3.x, I could do:
public void writeRequested(ChannelHandlerContext chctx, MessageEvent e)
{
if(e.getMessage() instanceof ServerMessage) //change
{
ServerMessage message = (ServerMessage) e.getMessage();
Channels.write(chctx,e.getFuture(),message.getData());
logger.debug("Message sent (id: "+message.getMessageID()+ " data: "+message.getMessageBody()+")");
}
else if(e.getMessage() instanceof String)
{
String data =(String)e.getMessage();
ChannelBuffer buffer = ChannelBuffers.buffer(data.length());
buffer.writeBytes(data.getBytes());
Channels.write(chctx,e.getFuture(),buffer);
logger.debug("Written string (possible <policy-file-request />) to client #id ->" +
+Environment.getGameInstance().getManager().getSession(chctx.getChannel());
}
}
However, with 4.x, I am a bit confused to what I can use. I have partially implemented simple sending like so;
public void encode(ChannelHandlerContext ctx, ServerMessage msg, ByteBuf buffer) {
if(msg instanceof ServerMessage) {
ServerMessage message = (ServerMessage)msg;
ctx.channel().write(message.getData());
logger.debug("Message sent (id: "+message.getMessageID()+ " data: "+message.getMessageBody()+")");
}
else {
// string stuff here
}
}
My basic problem is that how would I go about writing a String as well as a ServerMesssage to the client?
(My String is a simple )
Any help is greatly appreciated!
Just use the common super-class of the two messages and then cast as you did in 3.x if you really want to use the same ChannelHandler for both Objects. Anyway I think it would be much more clean if you just use two different ChannelHandler.

Android/Java - ClassNotFoundException for ServerSocket and Socket communication

I'm developing an app where the phone (Android program) is the client trying to send data through a socket to a Java receiver program on my computer.
So far I've been able to send simple strings or whatever, but now I'm trying to send custom objects that I create. I should note that both programs are separate Eclipse projects, and I seem to be having trouble including the same custom class "Order" on the server side (even though I have Order.java in the src folder of the server project).
Some code, for reference:
Server:
private void run() throws Exception {
ServerSocket mySS = new ServerSocket(4443);
while(true) {
Socket SS_accept = mySS.accept();
InputStream is = SS_accept.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Order order = (Order) ois.readObject();
if (order!=null){
java.util.List<String> items = order.getOrders();
int chair = order.getChair();
int table = order.getTable();
double price = order.getPrice();
System.out.println("Table: "+ table + " || Chair: " +chair);
for(String food: items) {
System.out.println(food);
}
System.out.println("Price: $"+price);
}
is.close();
SS_accept.close();
mySS.close();
}
And the relevant part of the client:
try {
mySocket = new Socket(serverService.ipAddress, serverService.port);
os = mySocket.getOutputStream();
oos = new ObjectOutputStream(os);
} catch(Exception e) {
Toast.makeText(PlaceOrder.this, "Error - not connected to server.", Toast.LENGTH_SHORT).show();
}
try {
oos.writeObject(order);
Toast.makeText(PlaceOrder.this, "Order Submitted!", Toast.LENGTH_SHORT).show();
refreshOrderPage(); //refresh page, allow waiter to make more orders
oos.close();
os.close();
mySocket.close();
} catch (Exception e) {
Toast.makeText(PlaceOrder.this, "Error - not connected to server.", Toast.LENGTH_SHORT).show();
}
Any ideas why I'm getting this error when trying to send objects through sockets?
Thanks.
You should probably set the serialVersionUID in the class, then build a jar with the shared classes and include that jar in both projects.
However, given you are using different JVMs (Oracle and Dalvik) there's no guarantee that the byte-level encoding is the same. You should either manually override the serialization using readObject/writeObject or use a different object encoding system that is guaranteed to be identical independent of the environment.
A stack trace would help, but almost certainly you're serializing an object on one side, sending it to the other, and the other side doesn't have a class definition with which it can reconstruct the object. In this case, it sounds like maybe your Server doesn't know about the com.foo.Order class.
You can also serialize object to some string format (json, yaml, xml) and pass it. It would much easier to maintain, I suppose.

Categories

Resources