Add Jersey client to my Android application.Illegal Argument Exception occured? - java

I want to use Jersey Client in my Android application.
This is the code for my client:
private JSONArray getJsonElements(){
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(getBaseURI());
JSONArray jarray = new JSONArray();
jarray = service.path("/collection").accept(MediaType.APPLICATION_JSON).get(JSONArray.class);
Log.v(TAG, jarray.toString());
return jarray;
}
private static URI getBaseURI() {
return UriBuilder.fromUri("http://localhost:6577/Example/rest/Example")
.build();
}
And here comes the problem.When i want to build application it gives me this very common exception:
java.lang.IllegalArgumentException: already added: Ljavax/ws/rs/core/GenericEntity;...2012-07-07 16:48:32 - SM] Conversion to Dalvik format failed with error 1
I saw all questions that were asked about this exception.It is possible to remove Jars from BuildPath and change choice of client(or I can create my client),but I don't want to do this.
What can you recommend to me?

Take a look in this link : http://www.vogella.com/articles/AndroidNetworking/article.html
I myself prefer to use HTTP Client to connect the Android application to a Rest Service using Jersey since it supports the HTTP commands such as POST, PUT, DELETE, GET. For example to use GET command and trasferring data in JSON format:
public class Client {
private String server;
public Client(String server) {
this.server = server;
}
private String getBase() {
return server;
}
public String getBaseURI(String str) {
String result = "";
try {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpGet getRequest = new HttpGet(getBase() + str);
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
result = getResult(response).toString();
httpClient.getConnectionManager().shutdown();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return result;
}
private StringBuilder getResult(HttpResponse response) throws IllegalStateException, IOException {
StringBuilder result = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())), 1024);
String output;
while ((output = br.readLine()) != null)
result.append(output);
return result;
}
}
And then easily in another class you can:
Client client = new Client("http://localhost:6577/Example/rest/");
String str = client.getBaseURI("Example"); // Json format

Related

Send the requestbody of one API to another API

Here is my code
private static final String MEDIA_TYPE = "application/json";
private static final String FORMAT = "UTF-8";
private static String baseServiceUrl;
private static String apiServiceUrl;
#RequestMapping("/")
public ResponseEntity<?> getMessage() throws Exception {
logger.info("Started");
try {
messageProcessor.getMessage("test service");
// Read from request
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String data = buffer.toString();
StringRequestEntity requestEntity = null;
HttpClient httpclient = new HttpClient();
int statusCode;
logger.info("RequestBody"+data);
baseServiceUrl="http://localhost:8080/services";
apiServiceUrl="/services/rest/json";
StringBuffer eventResponse = new StringBuffer();
requestEntity = new StringRequestEntity(data, MEDIA_TYPE, FORMAT);
PostMethod postMethod = new PostMethod(baseServiceUrl+apiServiceUrl);
postMethod.setRequestEntity(requestEntity);
statusCode = httpclient.executeMethod(postMethod);
logger.info("Status code"+statusCode);
}
catch (Exception ex) {
logger.error("Exception occurs ", ex);
return new ResponseEntity("Internal server error !!", HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity("Successfully called the service!!", HttpStatus.OK);
}
I want to get the requestbody of one API and send to another API .And a json is my request body.But in this code,I got the status code as 400.Can anyone help me to solve the problem
I think you have appended the /services in the url twice. It should be like:
baseServiceUrl="http://localhost:8080/services";
apiServiceUrl="/rest/json";
In your code you are reading the request body as a string , could you share the request body that is logged.The HTTP response code 400 corresponds to BAD request . So probably, either the endpoint that you are trying to hit is different or the request body has an issue. Try removing the /services from your apiServiceUrl to correct the url path.Also, since you are most probably having a json as request body try the following approach :
String json = "{"id":1,"name":"xxxx"}";
StringEntity entity = new StringEntity(json);
postMethod.setEntity(entity);
postMethod.setHeader("Accept", "application/json");
postMethod.setHeader("Content-type", "application/json");
make sure that the string that you read from the request using BufferedReader reader = request.getReader(); is in appropriate json format.

Java 8: Apache HttpClient failing authentication

I am attempting to use Apache HttpClient API to access Atlassian Confluence wiki pages.
Here is my code:
public class ConcfluenceTest{
public static void main(String[] args) {
String pageID = "107544635";
String hostName = "valid_hostname";
String hostScheme = "https";
String username = "verified_username";
String password = "verified_password";
int port = 443;
//set up the username/password authentication
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(hostName, port, AuthScope.ANY_REALM, hostScheme),
new UsernamePasswordCredentials(username, password));
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credsProvider)
.build();
try {
HttpGet getRequest = new HttpGet("valid_url");
System.out.println(getRequest.toString());
HttpResponse response = client.execute(getRequest);
//Parse the response
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
} catch (UnsupportedEncodingException e) {
System.out.println(e.getStackTrace());
} catch (IOException e) {
System.out.println(e.getStackTrace());
}
}
}
When I attempt to execute this code, the printed response is the HTML of the Log In screen, which means that the authentication failed. This code does, however, return the correct response when I provide it with the URL to a page that is not restricted to registered users (i.e credentials aren't required). I also tried all permutations of port/scheme.
Can someone tell me what I am missing?
Afaik, if http-basic-auth is supported, something like
user:password#server:port/path
should work, too. You could see if that works with a browser.
If Confluence dosen't support basic auth, use firebug to find out the action of the login-form (eg. the path, something like /dologin.action), the method (POST) and the Names of the user/password fields.
With that information you can create a request like this:
HttpPost httpPost = new HttpPost(fullFormActionUrlWithServerAndPort);
List <NameValuePair> nvp = new ArrayList <NameValuePair>();
nvp.add(new BasicNameValuePair("name-of-the-user-field", "your-user-name"));
nvp.add(new BasicNameValuePair("name-of-the-pass-field", "your-password"));
httpPost.setEntity(new UrlEncodedFormEntity(nvp));

How to send cookies with AsyncTask?

I have a web server, where i log in in my android Application, after that loging i recive as an XML the user who logged with a field named token.
This token is used to keep open the session during next calls to webService, and it works sendidnt the token as a cookie named "acrsession" but it seems not working because everytime i tried to check if im logged in (using a get call named currentUser) it returns me forbidden, so i think it isnt working good.
Here is my AsyncTask class who do the calls to server.
public String getFileName() {
return FileName;
}
public void setFileName(String fileName) {
FileName = fileName;
}
private String Response;
private URI uriInfo;
private String FileName;
public WebServiceTask(int taskType, Context mContext, String processMessage,String token) {
this.taskType = taskType;
this.mContext = mContext;
this.processMessage = processMessage;
this.token=token;
}
public void addNameValuePair(String name, String value) {
params.add(new BasicNameValuePair(name, value));
}
public void showProgressDialog() {
pDlg = new ProgressDialog(mContext);
pDlg.setMessage(processMessage);
pDlg.setProgressDrawable(mContext.getWallpaper());
pDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDlg.setCancelable(false);
pDlg.show();
}
#Override
protected void onPreExecute() {
//hideKeyboard();
showProgressDialog();
}
protected String doInBackground(String... urls) {
String url = urls[0];
String result = "";
HttpResponse response = doResponse(url);
if (response == null) {
return result;
} else {
try {
result = inputStreamToString(response.getEntity().getContent());
} catch (IllegalStateException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
} catch (IOException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
return result;
}
#Override
protected void onPostExecute(String response) {
this.Response=response;
pDlg.dismiss();
}
// Establish connection and socket (data retrieval) timeouts
private HttpParams getHttpParams() {
HttpParams htpp = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(htpp, CONN_TIMEOUT);
HttpConnectionParams.setSoTimeout(htpp, SOCKET_TIMEOUT);
return htpp;
}
private HttpResponse doResponse(String url) {
// Use our connection and data timeouts as parameters for our
// DefaultHttpClient
HttpClient httpclient = new DefaultHttpClient(getHttpParams());
int responseCode=0;
// Create a local instance of cookie store
//CookieStore cookieStore = new BasicCookieStore();
// Create local HTTP context
//HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
//localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
//CookieManager cookieManager= CookieManager.getInstance();
this.getLocalContext();
this.cookieStore.addCookie(new BasicClientCookie("acrsession", this.token));
HttpResponse response = null;
try {
switch (taskType) {
case POST_TASK:
HttpPost httppost = new HttpPost(url);
// Add parameters
httppost.setEntity(new UrlEncodedFormEntity(params));
int executeCount = 0;
do
{
pDlg.setMessage("Logging in.. ("+(executeCount+1)+"/5)");
// Execute HTTP Post Request
executeCount++;
response = httpclient.execute(httppost,localContext);
responseCode = response.getStatusLine().getStatusCode();
// If you want to see the response code, you can Log it
// out here by calling:
// Log.d("256 Design", "statusCode: " + responseCode)
} while (executeCount < 5 && responseCode == 408);
uriInfo = httppost.getURI();
break;
case GET_TASK:
HttpGet httpget = new HttpGet(url);
response = httpclient.execute(httpget,localContext);
responseCode = response.getStatusLine().getStatusCode();
httpget.getRequestLine();
uriInfo = httpget.getURI();
break;
case PUT_TASK:
HttpPut httpput = new HttpPut(url);
File file = new File(this.FileName);
InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(file), -1);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true); // Send in multiple parts if needed
httpput.setEntity(reqEntity);
response = httpclient.execute(httpput,localContext);
responseCode = response.getStatusLine().getStatusCode();
httpput.getRequestLine();
uriInfo = httpput.getURI();
break;
}
} catch (Exception e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return response;
}
private String inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
// Read response until the end
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
// Return full string
this.Response=total.toString();
return total.toString();
}
public String getResponse(){
return this.Response;
}
public HttpContext getLocalContext()
{
if (localContext == null)
{
localContext = new BasicHttpContext();
cookieStore = new BasicCookieStore();
localContext.setAttribute(ClientContext.COOKIE_ORIGIN, cookieStore);
localContext.setAttribute(ClientContext.COOKIE_SPEC, cookieStore);
localContext.setAttribute(ClientContext.COOKIESPEC_REGISTRY, cookieStore);
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);// to make sure that cookies provided by the server can be reused
}
return localContext;
}
Plesae tell me what im doing bad.
Thanks in advance.
Well, finally i found the solution, everything was ok but i fortgot to set cookie Domain and path, so onced i putted it it worked.
Now cookie creation looks like this:
this.localContext=this.getLocalContext();
BasicClientCookie cookie = new BasicClientCookie("acrsession", this.token);
cookie.setDomain(this.Domain);
cookie.setPath(this.path);
this.cookieStore.addCookie(cookie);
localContext.setAttribute(ClientContext.COOKIE_STORE, this.cookieStore);
Hope it will help someone else.

apache httpcomponents.httpClient strangest error ever

we are developing an android app and my current part is to implement uploading files.
I'm using httpcore-4.2.2, httpclient-4.2.2 and httpmime-4.2.2.
My problem now is that the file will only be send with the httpclient if the URI has a really specific description... if I use another URI the post-body on the server-side is empty... and I am really not capable of understanding this issue.
My code looks as follows:
public static String getUploadLink() {
String server = Mobile4dApplication.getContext().getString(R.string.default_server_address);
String parameter = "/Files/upload";
String finalQuery = String.format("%s%s", server, parameter);
Log.d("UploadService", finalQuery );
return finalQuery;
}
private String uploadFile(String uploadURL, File uploadFile, String title, long id) throws UnsupportedEncodingException, FileNotFoundException {
MultipartEntity multipartEntity = new MultipartEntity( );
multipartEntity.addPart( "file", new FileBody( uploadFile ) );
HttpResult httpResult;
try {
httpResult = HttpCommunicator.sendPOST( uploadURL, multipartEntity );
} catch (IOException e) {
e.printStackTrace();
return null;
}
// TODO remove sysout line when it is not needed anymore
System.out.println("result: " + httpResult.getResultMessage());
return httpResult.getResultMessage();
}
public static HttpResult sendPOST(String targetURL, HttpEntity entity) throws IOException {
HttpClient httpClient = getHttpClient();
HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis);
HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);
HttpPost httppost = new HttpPost(targetURL);
httppost.setEntity(entity);
HttpResponse response = httpClient.execute(httppost);
String result = "";
if (response != null && response.getEntity() != null) {
result = EntityUtils.toString(response.getEntity(), UTF_8_ENCODING);
}
return new HttpResult(result, response.getStatusLine().getStatusCode());
}
if I use the URI serveraddress/Files/upload everything looks fine on the server side. But if I change the part with "Files/upload" even in the slightest the whole post-body turns out to be empty when it reaches our server...
I am completely out of ideas... I really hope that someone can help...

Migrate from Commons HttpClient to HttpComponents Client

I would like to migrate from Commons HttpClient (3.x) to HttpComponents Client (4.x) but having difficulty how to handle redirects. The code works properly under Commons HttpClient but breaks when migrated to HttpComponents Client. Some of the links get undesirable redirects but when I set "http.protocol.handle-redirects" to 'false' a large number links stop working altogether.
Commons HttpClient 3.x:
private static HttpClient httpClient = null;
private static MultiThreadedHttpConnectionManager connectionManager = null;
private static final long MAX_CONNECTION_IDLE_TIME = 60000; // milliseconds
static {
//HttpURLConnection.setFollowRedirects(true);
CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.getParams().setDefaultMaxConnectionsPerHost(1000); // will need to set from properties file
connectionManager.getParams().setMaxTotalConnections(1000);
httpClient = new HttpClient(connectionManager);
}
/*
* Retrieve HTML
*/
public String fetchURL(String url) throws IOException{
if ( StringUtils.isEmpty(url) )
return null;
GetMethod getMethod = new GetMethod(url);
HttpClient httpClient = new HttpClient();
//configureMethod(getMethod);
//ObjectInputStream oin = null;
InputStream in = null;
int code = -1;
String html = "";
String lastModified = null;
try {
code = httpClient.executeMethod(getMethod);
in = getMethod.getResponseBodyAsStream();
//oin = new ObjectInputStream(in);
//html = getMethod.getResponseBodyAsString();
html = CharStreams.toString(new InputStreamReader(in));
}
catch (Exception except) {
}
finally {
try {
//oin.close();
in.close();
}
catch (Exception except) {}
getMethod.releaseConnection();
connectionManager.closeIdleConnections(MAX_CONNECTION_IDLE_TIME);
}
if (code <= 400){
return html.replaceAll("\\s+", " ");
} else {
throw new Exception("URL: " + url + " returned response code " + code);
}
}
HttpComponents Client 4.x :
private static HttpClient httpClient = null;
private static HttpParams params = null;
//private static MultiThreadedHttpConnectionManager connectionManager = null;
private static ThreadSafeClientConnManager connectionManager = null;
private static final int MAX_CONNECTION_IDLE_TIME = 60000; // milliseconds
static {
//HttpURLConnection.setFollowRedirects(true);
CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
connectionManager = new ThreadSafeClientConnManager();
connectionManager.setDefaultMaxPerRoute(1000); // will need to set from properties file
connectionManager.setMaxTotal(1000);
httpClient = new DefaultHttpClient(connectionManager);
// HTTP parameters stores header etc.
params = new BasicHttpParams();
params.setParameter("http.protocol.handle-redirects",false);
}
/*
* Retrieve HTML
*/
public String fetchURL(String url) throws IOException{
if ( StringUtils.isEmpty(url) )
return null;
InputStream in = null;
//int code = -1;
String html = "";
// Prepare a request object
HttpGet httpget = new HttpGet(url);
httpget.setParams(params);
// Execute the request
HttpResponse response = httpClient.execute(httpget);
// The response status
//System.out.println(response.getStatusLine());
int code = response.getStatusLine().getStatusCode();
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if (entity != null) {
try {
//code = httpClient.executeMethod(getMethod);
//in = getMethod.getResponseBodyAsStream();
in = entity.getContent();
html = CharStreams.toString(new InputStreamReader(in));
}
catch (Exception except) {
throw new Exception("URL: " + url + " returned response code " + code);
}
finally {
try {
//oin.close();
in.close();
}
catch (Exception except) {}
//getMethod.releaseConnection();
connectionManager.closeIdleConnections(MAX_CONNECTION_IDLE_TIME, TimeUnit.MILLISECONDS);
connectionManager.closeExpiredConnections();
}
}
if (code <= 400){
return html;
} else {
throw new Exception("URL: " + url + " returned response code " + code);
}
}
I won't want redirects but under HttpClient 4.x if I enable redirects then I get some that are undesirable, e.g. http://www.walmart.com/ => http://mobile.walmart.com/. Under HttpClient 3.x no such redirects happens.
What do I need to do to migrate HttpClient 3.x to HttpClient 4.x without breaking the code?
It is not the issue with HttpClient 4.x, might be the way target server handle the request, since the user agent is httpclient, it may be handled as mobile (target server may consider other than available browsers like, i.e, chrome, mozilla etc as mobile.)
Please use below code to set it manually
httpclient.getParams().setParameter(
org.apache.http.params.HttpProtocolParams.USER_AGENT,
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2"
);

Categories

Resources