Question

Edit: to simplify my question, has anyone managed to communicate with Activiti using rest?, and if so could you be kind to post your code. thanks.

I've been struggeling for a while to login to Activiti using Rest. I followed the api guides and implemented the following

Code:

package demo;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider;

public class Aloha {

   /**
    * @param args
    */
   public static void main(String[] args) {
      // TODO Auto-generated method stub

      Client client = Client.create();
      WebResource webResource = client
            .resource("http://localhost:8080/activiti-rest/service/login");
      MultivaluedMap<String, String> formData = new MultivaluedMapImpl();
      formData.add("userId", "kermit");
      formData.add("password", "kermit");
      ClientResponse response;
      try {
         response = webResource.type("application/x-www-form-urlencoded")
               .post(ClientResponse.class, formData); // webResource.accept(MediaType.TEXT_PLAIN_TYPE).post(ClientResponse.class,
                                             // formData);
         System.out.print(response.toString());
      } catch (UniformInterfaceException ue) {
         System.out.print(ue.getMessage());
      }

   }

}

As you can see I am using Jersey to consume the webservice, and here is the response I am getting all time:

Quote:

POST http://localhost:8080/activiti-rest/service/login returned a response status of 415 Unsupported Media Type

Please could you point out what I am doing wrong here?

Please note that when I replace the type with "application/json" i get the follow error:

Code:

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class com.sun.jersey.core.util.MultivaluedMapImpl, and MIME media type, application/json, was not found
   at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:149)
   at com.sun.jersey.api.client.Client.handle(Client.java:648)
   at com.sun.jersey.api.client.WebResource.handle(WebResource.java:670)
   at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
   at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:563)
   at demo.Aloha.main(Aloha.java:32)
Caused by: com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class com.sun.jersey.core.util.MultivaluedMapImpl, and MIME media type, application/json, was not found
   at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:288)
   at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:204)
   at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147)
   ... 5 more

Many Thanks,

Was it helpful?

Solution

Try the following:

  • Include jersey-json module in your dependencies
  • Create a new class named LoginInfo, annotated with @XmlRootElement annotation, having two public fields - userId and password
  • Initialize the LoginInfo class instance with the right userId and password
  • Pass it to the login call

Here is the code for the LoginInfo class:

@XmlRootElement
public class LoginInfo {
    public String userId;
    public String password;
}

Here is the code for the main() method:

  Client client = Client.create();
  WebResource webResource = client
        .resource("http://localhost:8080/activiti-rest/service/login");
  LoginInfo loginInfo = new LoginInfo();
  loginInfo.userId = "kermit";
  loginInfo.password = "kermit";
  ClientResponse response;
  try {
     response = webResource.type("application/json").post(ClientResponse.class, loginInfo);
     System.out.print(response.toString());
  } catch (UniformInterfaceException ue) {
     System.out.print(ue.getMessage());
  }

Note: I haven't tried this, maybe there are some typos or so. Also the LoginInfo can be turned into a real bean with setters/getters and stuff, just wanted to keep it simple. See if it works...

OTHER TIPS

As an alternative to jersey, This code uses Restlet to interact with Activiti using Rest.

This code are from Activiti in Action- Chapter 8. All credit should goes to Tijs Rademakers.

public class ActivitiRestClient {

    private static String REST_URI = "http://localhost:8080/activiti-rest/service";
    private static Logger logger = Logger.getLogger(ActivitiRestClient.class);

    private static ClientResource getClientResource(String uri) {
        ClientResource clientResource = new ClientResource(uri);
        clientResource.setChallengeResponse(ChallengeScheme.HTTP_BASIC,
                "kermit", "kermit");
        return clientResource;
    }
....
}

The error

Caused by: com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class com.sun.jersey.core.util.MultivaluedMapImpl, and MIME media type, application/x-www-form-urlencoded, was not found at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:299) at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:203) at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:146) ... 8 more

can also have it roots in maven dependencies. In my case I ended up replacing all the single Jersey artifacts like

  • jersey-server
  • jersey-json
  • jersey-client

with one jersey-bundle.

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-bundle</artifactId>
        <version>1.14</version>
    </dependency>

I had the same issue which got solved by removing the dependency on jersey-multipart-1.19.jar. I was getting the above exception when a common dependency jar was built which included the jersey bundle and the multipart jar. Separating them solved the issue.

Though this is an old post but I thought I should share my code based on HTTPClient version 4.1.3. I had a similar problem getting authentication mechanism work with Activiti REST. Though this post covers solutions based on Jersey and Restlet, I thought it would be helpful to post a solution based on HTTPClient.

Create the HTTPClient. Please note that it also creates the TargetHost (which is used to execute an action:

public HttpClient createHttpClient() {

targetHost = new HttpHost(REST_HOST_NAME, REST_PORT, REST_PROT);

Credentials defaultcreds = new UsernamePasswordCredentials(USERNAME, PWD);

AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());

HttpClient client = new DefaultHttpClient();
((DefaultHttpClient)client).getCredentialsProvider().setCredentials(authScope, defaultcreds);
 return client;
}

Create HTTP Context:

public BasicHttpContext createLocalContext() {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();

// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return localContext;
}

Add a method to get the target host:

public HttpHost getTargetHost() {
//created in the createHttpClient Method
return this.targetHost;
}

Finally invoke the REST:

public JSONObject invokeGetWS() throws ClientProtocolException, IOException {
ResponseHandler<String> responseHandler = new BasicResponseHandler();

HttpClient client = createHttpClient();

HttpGet httpGet = new HttpGet(ws_url); 
//ws_url is created at run time e.g http://localhost:9090/activiti-rest/service/user/kermit
System.out.println("executing request: " + httpGet.getRequestLine());

String responseBody = client.execute(getTargetHost(), httpGet, responseHandler, createLocalContext());
System.out.println("----------------------------------------");
System.out.println(responseBody);
System.out.println("----------------------------------------");

return new JSONObject(responseBody);
}

I suppose the variable names would be self explanatory. Thanks

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.MediaType;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.ClientResource;

public static boolean getAuthenticationSuccess(String username, String password) throws Exception {
    String uri = REST_URI + "/login";
    JSONStringer jsRequest = new JSONStringer();
    jsRequest.object();
    jsRequest.key("userId").value(username);
    jsRequest.key("password").value(password);
    jsRequest.endObject();
    Representation rep = new JsonRepresentation(jsRequest);
    rep.setMediaType(MediaType.APPLICATION_JSON);
    ClientResource clientResource = new ClientResource(uri);

    try {
        JSONObject jsObj = new JSONObject(clientResource.post(rep).getText());
        return jsObj.getBoolean("success");
    } catch (Exception e) {
        // TODO: handle exception
        logger.info("Erreur " + e.getMessage());

        return false;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top