Liferay WebServices

Liferay offers the potential to use it's services via WebServices. If you need an overview over all available WebServices just take a look at: http://*your.portal.url*/api/jsonws. Your custom Services created with Liferay's ServiceBuilder will also be listed here.

import com.liferay.portlet.asset.model.AssetEntrySoap;
import com.liferay.portlet.asset.model.AssetVocabularySoap;
import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
import java.util.List;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import org.json.JSONException;
import org.json.JSONObject;

public class WebServicesClient 
{
    private Client client;
    private WebTarget target;
    
    public WebServicesClient( final String portalUrl, final String username, final String password )
    {
        client = ClientBuilder.newClient();       
        client.register( new Authenticator( username, password ) );  
        client.register( GensonProvider.class );
        target = client.target( portalUrl + "api/jsonws" );        
    }

 public AssetEntrySoap requestAssetEntry( final String entryId ) 
    { 
        Form form = new Form();
        form.param( "entryId", entryId );

        AssetEntrySoap assetEntry = target.path( "/assetentry/get-entry" )
            .request( MediaType.APPLICATION_JSON_TYPE )
            .post( Entity.entity( form, MediaType.APPLICATION_FORM_URLENCODED_TYPE ), AssetEntrySoap.class );

        return assetEntry;
    }
 
    public List getAssetEntries(final String companyId ) 
    { 
        Form form = new Form();
        form.param( "companyId", companyId );
        form.param( "start", "-1" );
        form.param( "end", "-1" );

        List< AssetEntrySoap > assetEntries = target.path( "/assetentry/get-company-entries" )
            .request( MediaType.APPLICATION_JSON_TYPE )
            .post( Entity.entity( form, MediaType.APPLICATION_FORM_URLENCODED_TYPE ), new GenericType< List< AssetEntrySoap > >() { } );
   
        return assetEntries;
    }
}

To perform a valid authentication you can implement an authenticator like this:

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.MultivaluedMap;
import javax.xml.bind.DatatypeConverter;

public class Authenticator implements ClientRequestFilter 
{ 
 private final String username;
    private final String password;

    public Authenticator( final String username, final String password ) 
    {
        this.username = username;
        this.password = password;
    }

    public void filter( final ClientRequestContext requestContext ) throws IOException 
    {
        MultivaluedMap headers = requestContext.getHeaders();
        final String basicAuthentication = getBasicAuthentication();
        headers.add( "Authorization", basicAuthentication );
    }

    private String getBasicAuthentication() 
    {
        String token = this.username + ":" + this.password;
        try{
            return "BASIC " + DatatypeConverter.printBase64Binary( token.getBytes( "UTF-8" ) );
        }catch ( UnsupportedEncodingException ex ){
            throw new IllegalStateException( );
        }
    } 
}

If you use Genson for Building your json String, you will have to set useDateAsTimestamp as true in your GensonBuilder, since Liferay uses timestamps as date-fields.

import com.owlike.genson.Genson;
import com.owlike.genson.GensonBuilder;
import javax.ws.rs.ext.ContextResolver;

public class GensonProvider implements ContextResolver< Genson > 
{
    private final Genson genson = new GensonBuilder().useDateAsTimestamp( true ).create();

    @Override
    public Genson getContext( final Class< ? > arg0 ){
        return genson;
    }
}

Leave a Reply