I was trying to simplify the following lines with java 8

this.audiencias = new ArrayList<>();
        for(Audiencia audiencia: carpeta.getAudiencias()){
            this.audiencias.add(new AudienciaDTO(audiencia));
        }

to this

this.audiencias = carpeta.getAudiencias.stream().map(AudienciaDTO::new).collect(Collectors.toList());

although it seems correct, and no error was thrown, it was returning an empty list.

As it happens, the list type is important. The attribute this.audiencias is of type Collection and carpeta.getAudiencias returns the same type, but the method stream() apparently only works with List types.

If I change the code to

List<Audiencia> asList = new ArrayList(carpeta.getAudiencias());
        this.audiencias = asList.stream().map(AudienciaDTO::new).collect(Collectors.toList());

it works as expected, but it is cumbersome the need to convert the Collection to a List type first.

for a one liner it would be

this.audiencias = new ArrayList<>(carpeta.getAudiencias()).stream().map(AudienciaDTO::new).collect(Collectors.toList());

fuentes:
http://tutorials.jenkov.com/java-collections/streams.html
https://docs.oracle.com/javase/tutorial/collections/interfaces/index.html

Anuncios

En un servicio REST (jax-rs) puedes enviar los parámetros de una petición de varias formas: en la URL (@QueryParam), en el cuerpo del mensaje con el encabezado “application/x-www-form-urlencoded” (@FormParam), como parte de la URL (@PathParam).

Pero que pasa si el cliente envía toda la información en el cuerpo del mensaje en formato JSON.
Por ejemplo:

    {
        "tipo":"URGENTE",
        "actores":[
        {
            "nombre":"Juan",
            "apellidos":"Peréz",
            "idEstado":null,
            "idMunicipio":null,
            "idColonia":null,
            "calle":"Calle 2",
            "numero":"155",
            "codigoPostal":"76800"
        }
        ],
        "demandados":[
        {
            "nombre":"María",
            "apellidos":"López",
            "idEstado":null,
            "idMunicipio":null,
            "idColonia":null,
            "calle":"Calle 4",
            "numero":"45",
            "codigoPostal":"76800"
        }
        ]
    }

Podríamos crear una clase que reflejará esta estructura, pero si solo nos interesa algún campo o la petición no tiene nada que ver con nuestro modelo, no parece la mejor opción.

En este caso, en nuestro modelo existiría una clase Actor y Demandado que comparten los mismos campos, por lo que podríamos usar la herencia.

    public class Parte {
        String id;
        String nombre;
        String apellidos;
        String idEstado;
        String idMunicipio;
        String idColonia;
        String calle;
        String numero;
        String codigoPostal;
        public Parte() {
        }
        //... getter's y setter's, métodos, etc.
    }
    public class Actor extends Parte{
        //... otras propiedades
        public Actor() {
        }
        //... otros métodos
    }
    public class Demandado extends Parte{
        //... otras propiedades
        public Actor() {
        }
        //... otros métodos
    }

en nuestro servicio REST (Apache CXF) podríamos deserializar el arreglo de Actores de la siguiente forma

    @Path("solicitar/")
    public String solicitar(String data){
        String response = null;
        try{
            ObjectMapper mapper=new ObjectMapper();
            mapper.configure(SerializationConfig.Feature.WRITE<em>DATES</em>AS<em>TIMESTAMPS, false);
            mapper.configure(Feature.FAIL</em>ON<em>UNKNOWN</em>PROPERTIES, false);
            Map<String, Object> map = mapper.readValue(data, new TypeReference<Map<String, Object>>(){});
            String tipo = (String) map.get("tipo");
            List
<Parte> actores = mapper.convertValue(map.get("actores"), new TypeReference
<List<Parte>>() {});
            //... registrar la solicitud
            response = mapper.writeValueAsString(actores);
        }catch(Exception e){
            String error = "Ocurrió un problema al hacer la solicitud";
            log.error(error, e);
            response = String.format("{\"response\":{\"status\": -1, \"data\": \"%s\"}}", error);
        }
        return response;
    }

Fuentes:
http://wiki.fasterxml.com/JacksonDataBinding
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-DealingwithParameters

Para facilitar el uso de servicios REST utilzamos JavascriptObject overlay types, los cuales nos permiten obtener un objeto a partir de una cadena JSON. Los overlay types sólo permiten ciertos tipos de datos como parámetros o valores de retorno. Entonces, para obtener un Map a partir de una cadena JSON como la siguiente, podemos utilizar la clase JSOHelper del framewrok SmartGwt:

{“id”:”menu1″,”opciones”:{“key1″:”value1″,”key2″:”value2″,”key3″:”value3”}}

tendríamos que hacerlo de la siguiente manera:

public class Menu extends JavaScriptObject{

public final native String getId()/*-{return this.id}-*/;

public final native JavaScriptObject getNativeOpciones()/*-{return this.opciones}-*/;

public final LinkedHashMap<String,String> getOpciones(){

LinkedHashMap<String,String> linkedMap=new LinkedHashMap<String,String>();

Map map=JSOHelper.convertToMap(getNativeOpciones());

Iterator iterator=map.entrySet().iterator();

while(iterator.hasNext()){

Map.Entry item=(Map.Entry)iterator.next();

linkedMap.put((String)item.getKey(),(String)item.getValue());

}

return linkedMap;

}

}