How can I use HashMaps in Web service using Apche axis? - java

I'm doing an assignment where I have to use a web service using apache axis (Using eclips Mars) to make a desktop application in Java. It has to use an existing dynamic web project I already created.
Web project was to add/remove companies and employee details in a (Oracle) database in a web interface. It worked as required. But when the web service was created, It doesn't allow me to create a web client. It gives this error:
IWAB0399E Error in generating Java from WSDL:
java.io.IOException: ERROR: Missing <soap:fault> element inFault "IOException"
in operation "IOException", in binding getCompanies
Apparently, it wont allow me to return HashMaps from methods I created. (When I changed my whole project without returning Hashmaps, I can create the client) But I need to get HashMaps.
Are there any way to get HashMaps from the web service I created ???
I've refereed This question in SO. But I have no idea what's the accepted answer was saying.
EDIT:
OK. Now I know that I can't use HashMaps in web services as they can't be marshal and unmarshal. Then I found This question which I tried. But the problem still stands. (I guess I didn't used the answer mentioned above correctly.) As a beginner in this field, I actually don't get how to wrap (Or serialize) Hashmap and retrieve it back. Can someone show an example ?

You can try to wrap your HashMap in a class and create a custom adapter using it with #XmlJavaTypeAdapter to allow JAXB to make the object serialisation correctly.
public class Response {
#XmlJavaTypeAdapter(MapAdapter.class)
HashMap<Integer, Student> students;
public HashMap<Integer, Student> getStudents() {
return students;
}
public void setStudents(HashMap<Integer, Student> map) {
this.students = map;
}
}
Then just use this class as a return value of your web method.
See more:
Doc API
Example

Related

Play Excel module weird behaviour

I am using Play with Excel module 1.2.3. In a controller, I get a list of Students by calling a method defined in the model - Student:
List<Student> students= Student.findStudents();
findStudents() is defined as:
public static List<Student> findStudents() {
List<Student> list = Student.find("colA != colB").fetch();
return list;
}
then I render the excel file by:
renderExcel("student_report");
Inside the excel template, I have used JXLS. For example:
<jx:forEach items="${students}" var="stu">
${stu.address.name} ${stu.name}
</jx:forEach>
Now, the weird thing happens. stu.name always get displayed fine. However, stu.address.name only get displayed when I have done something like System.out.println(student.address.name) in the code. Otherwise, the cell in the Excel report is blank.
Can anyone explain this?
N.B. Student lazily ref to address
Jxls uses Apache Jexl to process property expressions like stu.address.name. Jexl uses reflection to calculate the object property values.
But reflection and lazy loading do not go along because you work not with a real object but with a proxy object.
When you do System.out.println(student.address.name) the real object is instantiated and the reflection works fine.
Possible solution to the issue is described in this answer Converting Hibernate proxy to real object. Or you just should do eager fetching whenever you need to pass the object to Jxls.

Fetching selected Data

I am new to spring I want to get all the data whose id=given by me. Can any one tell me how can I do That
#Override
public Collection<Device> listDevice() {
Collection<Device> deviceCollection=new ArrayList<>();
Iterable<Device> deviceIterable=deviceRepository.findAll();
for(Device d:deviceIterable){
deviceCollection.add(d);
}
return deviceCollection;
}
This is giving me all the data But I want data having id
long id=device.getManufacturer_id();
please tell how to do that
Instead of Repository#findAll, use Repository#findById(ID primaryKey).
Check this documentation:
http://docs.spring.io/spring-data/jpa/docs/1.0.0.M1/reference/html/
Instead try SpringDao library for JDBC related operations in Spring framework. It gives lots of pre built classes for requirements like your like NamedParameterJdbcDaoSupport, JdbcDaoSupport etc.
Will find host of examples of that on the net. just google it.

Google App Engine class on client side

I am developing an Android app using GAE on Eclipse.
On one of the EndPoint classes I have a method which returns a "Bla"-type object:
public Bla foo()
{
return new Bla();
}
This "Bla" object holds a "Bla2"-type object:
public class Bla {
private Bla2 bla = new Bla2();
public Bla2 getBla() {
return bla;
}
public void setBla(Bla2 bla) {
this.bla = bla;
}
}
Now, my problem is I cant access the "Bla2" class from the client side. (Even the method "getBla()" doesn't exist)
I managed to trick it by creating a second method on the EndPoint class which return a "Bla2" object:
public Bla2 foo2()
{
return new Bla2();
}
Now I can use the "Bla2" class on the client side, but the "Bla.getBla()" method still doesn't exit. Is there a right way to do it?
This isn't the 'right' way, but keep in mind that just because you are using endpoints, you don't have to stick to the endpoints way of doing things for all of your entities.
Like you, I'm using GAE/J and cloud endpoints and have an ANdroid client. It's great running Java on both the client and the server because I can share code between all my projects.
Some of my entities are communicated and shared the normal 'endpoints way', as you are doing. But for other entities I still use JSON, but just stick them in a string, send them through a generic endpoint, and deserialize them on the other side, which is easy because the entity class is in the shared code.
This allows me to send 50 different entity types through a single endpoint, and it makes it easy for me to customize the JSON serializing/deserializing for those entities.
Of course, this solution gets you in trouble if decide to add an iOS or Web (unless you use GWT) client, but maybe that isn't important to you.
(edit - added some impl. detail)
Serializing your java objects (or entities) to/from JSON is very easy, but the details depend on the JSON library you use. Endpoints can use either Jackson or GSON on the client. But for my own JSON'ing I used json.org which is built-into Android and was easy to download and add to my GAE project.
Here's a tutorial that someone just published:
http://www.survivingwithandroid.com/2013/10/android-json-tutorial-create-and-parse.html
Then I added an endpoint like this:
#ApiMethod(name = "sendData")
public void sendData( #Named("clientId") String clientId, String jsonObject )
(or something with a class that includes a List of String's so you can send multiple entities in one request.)
And put an element into your JSON which tells the server which entity the JSON should be de serialized into.
Try using #ApiResourceProperty on the field.

On the client side, how should I be using complex type objects returned by a CXF webservice?

I've just started using CXF 2.4 to expose some methods in an existing web application. One of the methods returns a complex type object - Employee which has an Address object as a property.
The employee object looks like:
public class Employee implements Serializable {
private String gid;
private String name;
private Address employeeAddress;
//...getters and setters omitted
}
The method signature in the service side interface looks like:
Employee getEmployee(#WebParam(name="gid") String gid);
On the client side I used the CXF WsdlToJava utility to generate my client side stubs from the server wsdl address and was happily using the Employee object in my client web application.
Today a co-worker pointed out to me that I shouldn't be using the webservice generated objects in my client application code. Instead I should create an Employee class specific to my client web app and copy the properties from the web service Employee object to my application Employee object to prevent the web service code ending up throughout the code base.
To me this seems like overkill, in effect I'll create an Employee class plus an Address class and copy properties back and forth between objects of those types and those of the webservices.
In my application I'm displaying the details of the Employee object on a JSP page but not doing much else with it.
So to sum up my question - when using webservice calls in CXF which return complex type objects, should you always use separate client application specific objects which copy the properties of the webservice generated objects? Is there a rule to use or does it depend on how complex the objects returned are and what the client application intends to do with them (e.g. just display them, edit them and return them, store them in a client application db.)
Thanks
Darren
I don't see any problem in using webservice generated object on the client side.
And creating own class and move the prperties back and forth is just a time killing process.
When tool is providing you the implementation feature why we need to manually do the changes.If there is a valid point then need to be figure out.
So my answear is you can work with the webservice generated Employee class for your implementation.

Variable number of arguments in an Axis2 POJO

I have a web service that I built with Axis2/Java. The web service will take in a list of objects and will process them. I'll use the following operation as an example.
public class AddToDatabaseService{
public void addToDatabase(String name1, String name2, String name3, ....)
{
//add names to database
}
}
I want the caller of my web service to use a URI like:
http://localhost:8080/axis2/services/addToDatabase?name1=Joe&name2=Bob&name3=Kelly&name4=...
I'm aware this is not compilable code and the idea is still there. Is this even possible with SOAP-based web services? I know this is possible to do with RESTful services because you can just take the HttpServletRequest request object and do Enumeration enumeration = request.getParameterNames() and iterate through them.
I'm looking for the equivalent of that in web services POJO's with Axis2.
A link or an sample program would be great!
Thanks.
Similar to the this question
Solution was to use a varargs parameter

Categories