0

i need return different Lists on a WebService, currently i have more than 15 different types in an encapsulate file but is very hard manipulate many constructors:

public class ResponseMessage implements java.io.Serializable {

    private Integer code;
    private String message;
    private List<Users> listUsers;
    private List<Products> listProducts;
    private List<Customers> listCustomers;
    private List<Suppliers> listSuppliers;
    private List<Reports> listReports;
    ...
    private Users userById;
    private Products productById;
    private Customers customerById;
    private Suppliers supplierById;
    ...

    public ResponseMessage() {
    }

    //My idea is something like that, not work
    public ResponseMessage(Integer code, String message, List<T> lstData) {
        this.code = code;
        this.message = message;
        this.lstData = lstData;
    }

    public ResponseMessage(Integer code, String message, T uniqueData) {
        this.code = code;
        this.message = message;
        this.uniqueData = uniqueData;
    }

    //Currently the constructor are this, work
    public ResponseMessage(Integer code, String message, List<Users> listUsers) {
        this.code = code;
        this.message = message;
        this.listUsers = listUsers;
    }

    public ResponseMessage(Integer code, String message, List<Users> listUsers, List<Customers> listCustomers) {
        this.code = code;
        this.message = message;
        this.listUsers = listUsers;
        this.listCustomers = listCustomers;
    }

    public ResponseMessage(Integer code, String message, List<Users> listUsers, List<Customers> listCustomers, List<Suppliers> listSuppliers) {
        this.code = code;
        this.message = message;
        this.listUsers = listUsers;
        this.listCustomers = listCustomers;
        this.listSuppliers = listSuppliers;
    }

    ...

    //Same history with unique result, work
    public ResponseMessage(Integer code, String message, Users userById) {
        this.code = code;
        this.message = message;
        this.userById = userById;
    }

    public ResponseMessage(Integer code, String message, Users userById, Products productById) {
        this.code = code;
        this.message = message;
        this.userById = userById;
        this.productById = productById;
    }

    //Getters and Setters
}

When i like return the constructor on the WebService i have to do it this, for example (work):

public ResponseMessage readAllSuppliers() {
   List<Suppliers> lstsuppliers = new ArrayList<Suppliers>();
   lstsuppliers = supplierDAO.getAllSuppliers();
   //ResponseMessage(code, message, user, customer, supplier list or unique supplier)
   ResponseMessage rm = new ResponseMessage(123, "reading suppliers", null, null, lstsuppliers);
   return rm;
}

But i think you can do it like this for anyone list:

public ResponseMessage readAllSuppliers() {
    List<Suppliers> lstsuppliers = new ArrayList<Suppliers>();
    lstsuppliers = supplierDAO.getAllSuppliers();
    //ResponseMessage(code, message, list or object data)
    ResponseMessage rm = new ResponseMessage(123, "reading suppliers", lstsuppliers);
    return rm;
}

At the end, get the info data something like this on a WebService Client:

public void getSuppliers() {
    WebServiceResponse wsr = new WebServiceResponse();
    ResponseMessage rm = wsr.readAllSuppliers();
    System.out.println("CODE: " + rm.getCode()); //CODE: 123
    System.out.println("MESSAGE: " + rm.getMessage()); //MESSAGE: reading suppliers
    for (Suppliers data : rm.getLstData()) {
       System.out.println("SUPPLIER INFO: " + data.getFullName()); 
    }
    //SUPPLIER INFO: Name1 Surname1
    //SUPPLIER INFO: Name2 Surname2
    //SUPPLIER INFO: Name3 Surname3
}

I hope you can help me

P.J.Meisch
  • 18,013
  • 6
  • 50
  • 66
  • Check out the Builder Pattern: https://en.wikipedia.org/wiki/Builder_pattern – Shadov May 31 '17 at 09:47
  • One more way you can do is to send a `HashMap` with `keys` that are the `types of list (user,customers)` and the `corresponding lists` as `values`. You can have just one constructor which takes in `HashMap` as an argument. In your constructor, you can have code to set all the lists by getting from the map. Since `HashMap` operations are `O(1)`, it does not have much impact on performance as well. – v1shnu May 31 '17 at 09:56

2 Answers2

0

You just need to add <T> after your ResponseMessage declaration to tell Java you want to use generics. Hope this helps. Note it expects to give back one type only per response. If you need to send more than one type, it might be a good idea to use a Map of Types to Lists instead of lstData as mentioned by @v1shnu.

public class ResponseMessage<T> implements Serializable {

    private final List<T> lstData;
    private final Integer code;
    private final String message;

    public ResponseMessage(Integer code, String message, List<T> lstData) {
        this.code = code;
        this.message = message;
        this.lstData = lstData;
    }
}

You could consider doing the same thing for your data access objects.

Sam
  • 670
  • 1
  • 6
  • 20
  • i tried it that way and doesn't work, when i call the supplier method show me the next error: javax.xml.bind.JAXBException: class Supplier nor any of its super class is known to this context – M. Flores Jun 02 '17 at 00:24
  • Getting the next error sounds like progress to me! Take a look at this: https://stackoverflow.com/questions/14057932/javax-xml-bind-jaxbexception-class-nor-any-of-its-super-class-is-known-to-t – Sam Jun 02 '17 at 09:27
  • but the coding is in REST and i working SOAP, the syntax changes, i can't adapt it :( – M. Flores Jun 10 '17 at 03:35
0

You can create an HashMap , before you send it to ResponseMessage like below :

Map<String,List<T>> listsMap = new HashMap<>();
listsMap.put("users",userDao.readAllUsers());
listsMap.put("customers",customerDao.readAllCustomers());
listsMap.put("suppliers",supplierDao.readAllSuppliers());

ResponseMessage rm = new ResponseMessage(123, "message", listsMap);

In your ResponseMessage class, you can add a constructor like below :

public ResponseMessage (Integer code, String message,Map listsMap){
    this.code = code;
    this.message = message;
    this.listUsers = (List<Users>) listsMap.get("users");
    this.listCustomers = (List<Customers>) listsMap.get("customers");
    this.listSuppliers = (List<Suppliers>) listsMap.get("suppliers");
}
v1shnu
  • 2,211
  • 8
  • 39
  • 68
  • appears the next error: `java.util.List is an interface, and JAXB can't handle interfaces. this problem is related to the following location: at java.util.List at public java.util.Map ResponseMessage.getListsMap()` – M. Flores Jun 02 '17 at 01:21