I have developed a simple java program to fetch the data of issues/user stories.
I want to fetch 'description' field of a perticular issue. I have used GET method to get response but I'm getting errors while connecting to JIRA.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class JiraIssueDescription {
public static void main(String[] args) {
try {
URL url = new URL("https://****.atlassian.net/rest/agile/1.0/issue/41459");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("username", "***#abc.com");
conn.setRequestProperty("password", "****");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
When I run the project I get following error
java.net.UnknownHostException: ****.atlassian.net
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
at sun.security.ssl.BaseSSLSocketImpl.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at com.JiraIntegration.bean.JiraIssueDescription.main(JiraIssueDescription.java:24)
Can anyone please help me with the errors. Do I need to implement OAuth ?
UnknownHostException looks like you have a typo in your URL or are facing some proxy issues .
Does it work in your Browser?
It should give you some json in response. Like this:
https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658
You could also test with other tools like curl. Does it work?
curl https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658
Atlassian rest API provides two authentication methods, Basic auth and Oauth. Use this approach to create a valid basic auth header or try the request without parameters.
The following code demonstrates how it should work:
package stack48618849;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.junit.Test;
public class HowToReadFromAnURL {
#Test
public void readFromUrl() {
try (InputStream in = getInputStreamFromUrl("https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658")) {
System.out.println(convertInputStreamToString(in));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Test(expected = RuntimeException.class)
public void readFromUrlWithBasicAuth() {
String user="aUser";
String passwd="aPasswd";
try (InputStream in = getInputStreamFromUrl("https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658",user,passwd)) {
System.out.println(convertInputStreamToString(in));
} catch (Exception e) {
System.out.println("If basic auth is provided, it should be correct: "+e.getMessage());
throw new RuntimeException(e);
}
}
private InputStream getInputStreamFromUrl(String urlString,String user, String passwd) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
String encoded = Base64.getEncoder().encodeToString((user+":"+passwd).getBytes(StandardCharsets.UTF_8));
conn.setRequestProperty("Authorization", "Basic "+encoded);
return conn.getInputStream();
}
private InputStream getInputStreamFromUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
return conn.getInputStream();
}
private String convertInputStreamToString(InputStream inputStream) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString("UTF-8");
}
}
This prints:
{"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations","id":"789521","self":"https://jira.atlassian.com/rest/api/2/issue/789521","key":"JSWCLOUD-11658","fields":{"customfield_18232":...
If basic auth is provided, it should be correct: Server returned HTTP response code: 401 for URL: https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658
Instead of a HttpURLConnection way of implementing, you could use Spring's RestTemplate in an efficient manner to solve your problem:
Providing you a piece of code that I use, with the JIRA REST APIs:
Create a RESTClient that you would want to use in conjunction with JIRA REST APIs as like the below:
public class JIRASpringRESTClient {
private static final String username = "fred";
private static final String password = "fred";
private static final String jiraBaseURL = "https://jira.xxx.com/rest/api/2/";
private RestTemplate restTemplate;
private HttpHeaders httpHeaders;
public JIRASpringRESTClient() {
restTemplate = new RestTemplate();
httpHeaders = createHeadersWithAuthentication();
}
private HttpHeaders createHeadersWithAuthentication() {
String plainCredentials = username + ":" + password;
byte[] base64CredentialsBytes = Base64.getEncoder().encode(plainCredentials.getBytes());
String base64Credentials = new String(base64CredentialsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Credentials);
return headers;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public ResponseEntity<String> getJIRATicket(String issueId) {
String url = jiraBaseURL + "issue/" + issueId;
HttpEntity<?> requestEntity = new HttpEntity(httpHeaders);
return restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
}
}
Then you can further re-use these methods as like the below:
public class JIRATicketGet {
public static void main(String... args) {
JIRASpringRESTClient restClient = new JIRASpringRESTClient();
ResponseEntity<String> response = restClient.getJIRATicket("XXX-12345");
System.out.println(response.getBody());
}
}
This will provide the GET response from JIRA, which is in JSON format which can be further manipulated to get the specific field from the GET response with the use of com.fasterxml.jackson.databind.ObjectMapper
Using the JSON that you get in the step above, you can create a POJO class (for example, Ticket) and then use it as follows:
ObjectMapper mapper = new ObjectMapper();
try {
Ticket response = mapper.readValue(response.getBody(), Ticket.class);
} catch (IOException e) {
e.printStackTrace();
}
Hope this helps!
Related
I am learning to use the JMockit to test my Restful API.The missing invocation error is abusing me.
The Restful API:
#RestController
public class AgentInfoRest {
#Autowired
AgentInfoRepository agentInfoRepository;
private Logger logger = LoggerFactory.getLogger(AgentInfoRest.class);
#RequestMapping("/allagentInfo")
RestResponse getAllAgentInfo()
{
RestResponse restResponse = new RestResponse();
logger.info("getAllAgentInfo has no request parameter");
Collection<AgentInfo> result = agentInfoRepository.getAllAgents();
if(result.isEmpty())
{
restResponse.setRetCode(-1);
restResponse.setRetMsg("Request success,no such record in db");
}
restResponse.setResult(result);
return restResponse;
}
}
The Test Class:
public class AgentInfoRestTest {
String host = "http://127.0.0.1:8080";
#Test
public void getAllAgentInfoTest(#Mocked final AgentInfoRepository agentInfoRepository) {
RestTemplate restTemplate = new RestTemplate();
RestResponse restResponse = new RestResponse();
AgentInfoRest agentInfoRest = new AgentInfoRest();
new StrictExpectations() {
{
agentInfoRepository.getAllAgents(); result = null; times = 1;
}
};
String url = "/allagentInfo";
ResponseEntity<RestResponse> result = restTemplate.getForEntity(host + url, RestResponse.class);
new FullVerifications() {
{
}
};
}
}
The Error:
mockit.internal.MissingInvocation: Missing invocation of:
com.egoo.dao.repository.freelink.AgentInfoRepository#getAllAgents()
on mock instance: com.egoo.dao.repository.freelink.$Impl_AgentInfoRepository#50a7bc6e
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:253)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: Missing invocation
at com.egoo.dao.rest.freelink.AgentInfoRestTest$1.(AgentInfoRestTest.java:33)
at com.egoo.dao.rest.freelink.AgentInfoRestTest.getAllAgentInfoTest(AgentInfoRestTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:498)
... 7 more
I create an application by using Bluemix's Liberty for Java to connect Cloudant. I found RuntimeException everyday while connecting to my RESTful API. However, I have to restart my application everyday to solve this problem.
An error is shown as follow:
Exception thrown by application class 'org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Error retrieving server response
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
at [internal classes]
Caused by: org.apache.cxf.interceptor.Fault: Error retrieving server response
at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:163)
... 1 more
Caused by: com.cloudant.client.org.lightcouch.CouchDbException: Error retrieving server response
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:501)
at com.cloudant.client.org.lightcouch.CouchDbClient.executeToInputStream(CouchDbClient.java:515)
at com.cloudant.client.api.Database.findByIndex(Database.java:361)
at com.cloudant.client.api.Database.findByIndex(Database.java:321)
at th.co.gosoft.rest.TopicService.getHotTopicList(TopicService.java:82)
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:636)
... 1 more
Caused by: java.net.ProtocolException: Server rejected operation
at sun.net.www.protocol.http.HttpURLConnection.expect100Continue(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(Unknown Source)
at com.cloudant.http.HttpConnection.execute(HttpConnection.java:231)
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:466)
... 9 more
I use this CloudantClientMgr as follow:
package th.co.gosoft.util;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map.Entry;
import java.util.Set;
import com.cloudant.client.api.ClientBuilder;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class CloudantClientMgr {
private static CloudantClient cloudant = null;
private static Database db = null;
private static String databaseName = "go10_db";
private static String url = "https://xxxxxxxxxx-bluemix.cloudant.com";
private static String user = "xxxxxxxxxx-bluemix";
private static String password = "password";
private static void initClient() {
if (cloudant == null) {
synchronized (CloudantClientMgr.class) {
if (cloudant != null) {
return;
}
try {
cloudant = createClient();
} catch (MalformedURLException e) {
throw new RuntimeException(e.getMessage(), e);
}
System.out.println("cloudant : " + cloudant.serverVersion());
}
}
}
private static CloudantClient createClient() throws MalformedURLException {
String VCAP_SERVICES = System.getenv("VCAP_SERVICES");
String serviceName = null;
CloudantClient client;
if (VCAP_SERVICES != null) {
System.out.println("VCAP_SERVICE");
JsonObject obj = (JsonObject) new JsonParser().parse(VCAP_SERVICES);
Entry<String, JsonElement> dbEntry = null;
Set<Entry<String, JsonElement>> entries = obj.entrySet();
for (Entry<String, JsonElement> eachEntry : entries) {
if (eachEntry.getKey().toLowerCase().contains("cloudant")) {
dbEntry = eachEntry;
break;
}
}
if (dbEntry == null) {
throw new RuntimeException("Could not find cloudantNoSQLDB key in VCAP_SERVICES env variable");
}
obj = (JsonObject) ((JsonArray) dbEntry.getValue()).get(0);
serviceName = (String) dbEntry.getKey();
System.out.println("Service Name - " + serviceName);
obj = (JsonObject) obj.get("credentials");
user = obj.get("username").getAsString();
password = obj.get("password").getAsString();
client = ClientBuilder.account(user)
.username(user)
.password(password)
.build();
} else {
System.out.println("LOCAL");
client = ClientBuilder.url(new URL(url))
.username(user)
.password(password)
.build();
}
return client;
}
public static Database getDB() {
if (cloudant == null) {
initClient();
}
if (db == null) {
try {
db = cloudant.database(databaseName, true);
} catch (Exception e) {
throw new RuntimeException("DB Not found", e);
}
}
return db;
}
private CloudantClientMgr() {
}
}
I use this code to connect CloudantClientMgr as follow:
#Path("topic")
public class TopicService {
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response createTopic(TopicModel topicModel) {
Database db = CloudantClientMgr.getDB();
com.cloudant.client.api.model.Response response = db.save(topicModel);
String result = response.getId();
return Response.status(201).entity(result).build();
}
}
The Cloudant version is 2.4.2
<dependency>
<groupId>com.cloudant</groupId>
<artifactId>cloudant-client</artifactId>
<version>2.4.2</version>
</dependency>
If anyone used to found this problem, please let me know the better solution than I have to restart my application every day.
The problem you describe sounds identical to one that was resolved in version 2.4.1.
I would check to make sure you don't have multiple versions of the cloudant-client included in your application or classpath and that your application is really using version 2.4.2. The line numbers in the stack trace you provide do not match with the source for 2.4.2.
i try to use apache httpclient as backend for jersey client to handle cookie automatically and here is my code
class ClientHelper {
public static HttpClientConnectionManager customConnectionManager() throws Exception {
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
System.out.println("========checkClientTrusted=========");
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
System.out.println("========checkServerTrusted==========");
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}}, new SecureRandom());
SSLConnectionSocketFactory
sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.build();
PoolingHttpClientConnectionManager phcc = new PoolingHttpClientConnectionManager(registry);
return phcc;
}
public static Client createClient() {
HttpClient apacheClient = null;
try {
apacheClient =
HttpClientBuilder.create().setConnectionManager(customConnectionManager()).build();
} catch (Exception e) {
e.printStackTrace();
}
Client client = new Client(new ApacheHttpClient4Handler(apacheClient,
new BasicCookieStore(),
true));
return client;
}
}
I try to use the apache httpclient as the backend of jersey client (in order to handle the cookie)
Then, I create a simple class to test client,
import com.sun.jersey.api.client.Client;
....
public class ApiTest {
private static Client client;
public String getAuth(String username, String passwd) {
Map<String, String> formParams = new HashMap<String, String>();
formParams.put("username", String.valueOf(username));
formParams.put("passwd", String.valueOf(passwd));
try {
String basePath = "https://xyzhost/login";
if (client == null) {
client = ClientHelper.createClient();
client.addFilter(new LoggingFilter(System.out));
}
WebResource webResource = client.resource(basePath);
ClientResponse response = webResource.type("application/x-www-form-urlencoded").accept("application/json")
.post(ClientResponse.class, processFormParams(formParams));
if (response != null) {
String authRes = response.getEntity(String.class);
response.close();
return authRes;
} else {
return null;
}
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
public String getSummary(){
try {
String basePath = "https://xyzhost/summary";
if (client == null) {
client = ClientHelper.createClient();
}
WebResource webResource = client
.resource(basePath);
ClientResponse response = webResource.type("application/x-www-form-urlencoded").accept("application/json")
.post(ClientResponse.class, processFormParams(formParams));
if (response != null) {
String serviceRes = response.getEntity(String.class);
response.close();
return serviceRes;
} else {
return null;
}
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
public static void main(String[] args) throws ApiException {
String username = "testuser";
String passwd = "testpasswd";
AuthApi apiTest = new ApiTest();
String auth =apiTest.getAuth(username, passwd);
String reslut1 = apiTest.getSummary();
String result2 = apiTest.getSummary();
String result3 = apiTest.getSummary();
String result4 = apiTest.getSummary();
}
}
So, I use the same client to hit the service under the same host.
I can success get the response for "auth" and "result1" but the client stuck in "result2" in the following part
ClientResponse response = webResource.type("application/x-www-form-urlencoded").accept("application/json")
.post(ClientResponse.class, processFormParams(formParams));
I try to modify the following part:
PoolingHttpClientConnectionManager phcc= new PoolingHttpClientConnectionManager(registry);
phcc.setDefaultMaxPerRoute(10);
then, ApiTest works, won't stuck. I guess there is some issue about the connection, since by default, the max per route for poolingHttpClientConnectionManager is 2, so my ApiTest will stuck in the 3rd request. I think the connection has been release since I have consume the response entity ,
if (response != null) {
String serviceRes = response.getEntity(String.class);
response.close();
return serviceRes;
}
but it seems not work at all, the connection seems not released.
anyone can help ? Appreciate!
I get one solution: switch the version of jersey-client from 1.17 to 1.18 , then problem solved!
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18</version>
<scope>compile</scope>
</dependency>
I have a wildcard cert for *.mydomain.com (the names have been changed to protect the innocent...that is NOT the real domain :) )
When using a correctly implemented Java HttpClient 4 (the issue is not seen in FF), Service calls made via HTTPS to api.mydomain.com are successful where as identical service calls made to non-production subdomains of mydomain.com (developer.mydomain.com, api-beta.mydomain.com, api-uat.mydomain.com) generate this Exception with the Test harness code below:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:397)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:573)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at com.mydomain.httpclientexample.HttpClientTestv2.main(HttpClientTestv2.java:54)
While the SLL cert on developer.mydomain.com, api-beta.mydomain.com & api-uat.mydomain.com appears to be the same WC cert as api.mydomain.com, the exception is not seen on api.mydomain.com but it is on the other sub-domains. The code works on api-na.mydomain.com and should work on the non-production subdomains.
Any ideas?
Client code: As you can see, I can easily change the ADDRESS_VALIDATION_SERVICE_URI I want to call. The api.mydomain.com one works without the SSLPeerUnverifiedException; the other three URIs throw the exception...
package com.mydomain.httpclientexample;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class HttpClientTestv2 {
//public final static String ADDRESS_VALIDATION_SERVICE_URI = "https://developer.mydomain.com/v1.0/stores/MYSTORE/address/validate.xml";
public final static String ADDRESS_VALIDATION_SERVICE_URI = "https://api-beta.mydomain.com/v1.0/stores/MYSTORE/address/validate.xml";
//public final static String ADDRESS_VALIDATION_SERVICE_URI = "https://api-uat.mydomain.com/v1.0/stores/MYSTORE/address/validate.xml";
//public final static String ADDRESS_VALIDATION_SERVICE_URI = "https://api.mydomain.com/v1.0/stores/MYSTORE/address/validate.xml";
public final static String APIKEY_ATTRIBUTE_NAME = "apikey";
public final static String APIKEY_ATTRIBUTE_VALUE = "2c90bc83e821364ffa557486c3e2a44e";
/**
* #param args
*/
public static void main(String[] args) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(ADDRESS_VALIDATION_SERVICE_URI);
System.out.println("executing request" + httpPost.getRequestLine());
//set a request header
httpPost.setHeader(APIKEY_ATTRIBUTE_NAME , APIKEY_ATTRIBUTE_VALUE);
//add the xml body
StringEntity postBody = null;
try {
postBody = new StringEntity(getXMLDoc(),"UTF-8");
} catch (UnsupportedEncodingException uee) {
System.out.println("----------------------------------------");
System.out.println("Exception Caught in UnsupportedEncodingException catch block");
System.out.println("----------------------------------------");
uee.printStackTrace();
}
httpPost.setEntity(postBody);
HttpResponse response;
try {
response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
System.out.println("Content:" + EntityUtils.toString(entity));
EntityUtils.consume(entity);
// entity.consumeContent();
}
} catch (ClientProtocolException e) {
System.out.println("----------------------------------------");
System.out.println("Exception Caught in ClientProtocolException catch block");
System.out.println("----------------------------------------");
e.printStackTrace();
} catch (IOException e) {
System.out.println("----------------------------------------");
System.out.println("Exception Caught in ClientProtocolException catch block");
System.out.println("----------------------------------------");
e.printStackTrace();
}
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
private static String getXMLDoc() {
StringBuffer XMLDoc = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?><AddressValidationRequest xmlns=\"http://api.mydomain.com/schema/checkout/1.0\">")
.append("<Header><MaxAddressSuggestions>5</MaxAddressSuggestions></Header>")
.append("<Address><Line1>17243 S. Mill Ln</Line1><Line2/><City>Ocean View</City><MainDivision>DE</MainDivision><CountryCode>US</CountryCode><PostalCode>19970</PostalCode></Address>")
.append("</AddressValidationRequest>");
return XMLDoc.toString();
}
}
I'm having a problem.
I'm developing web application in Eclipse IDE and using Tomcat 7.
Everything was working fine, when suddenly my debugger doesn't work anymore as it should and everything collapsed to pieces. I was looking for same errors, but I haven't found soulution yet. Please help me.
I'm getting this error:
SEVERE: Servlet.service() for servlet [FitbitApiAuthExampleServlet] in context with path [/Webfit] threw exception
java.lang.NullPointerException
at java.net.URLEncoder.encode(Unknown Source)
at com.fitbit.api.client.http.OAuth.encode(OAuth.java:254)
at com.fitbit.api.client.http.OAuth.encodeParameters(OAuth.java:233)
at com.fitbit.api.client.http.OAuth.encodeParameters(OAuth.java:217)
at com.fitbit.api.client.http.OAuth.normalizeRequestParameters(OAuth.java:196)
at com.fitbit.api.client.http.OAuth.generateAuthorizationHeader(OAuth.java:85)
at com.fitbit.api.client.http.OAuth.generateAuthorizationHeader(OAuth.java:129)
at com.fitbit.api.client.http.HttpClient.setHeaders(HttpClient.java:522)
at com.fitbit.api.client.http.HttpClient.httpRequest(HttpClient.java:422)
at com.fitbit.api.client.http.HttpClient.get(HttpClient.java:398)
at com.fitbit.api.client.FitbitApiClientAgent.httpGet(FitbitApiClientAgent.java:2563)
at com.fitbit.api.client.FitbitApiClientAgent.httpGet(FitbitApiClientAgent.java:2513)
at com.fitbit.api.client.FitbitApiClientAgent.getLoggedHeartRate(FitbitApiClientAgent.java:1779)
at com.fitbit.web.FitbitApiAuthExampleServlet.doGet(FitbitApiAuthExampleServlet.java:108)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Servlet code:
package com.fitbit.web;
import com.fitbit.api.FitbitAPIException;
import com.fitbit.api.client.*;
import com.fitbit.api.client.service.FitbitAPIClientService;
import com.fitbit.api.common.model.body.Body;
import com.fitbit.api.common.model.body.BodyWithGoals;
import com.fitbit.api.common.model.bp.Bp;
import com.fitbit.api.common.model.heart.Heart;
import com.fitbit.api.common.model.user.UserInfo;
import com.fitbit.api.model.APIResourceCredentials;
import com.fitbit.api.model.FitbitUser;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.LocalDate;
import java.io.IOException;
import java.util.Properties;
/**
* Created by IntelliJ IDEA.
* User: Kiryl
* Date: 6/22/11
* Time: 7:05 AM
*/
public class FitbitApiAuthExampleServlet extends HttpServlet {
public static final String OAUTH_TOKEN = "oauth_token";
public static final String OAUTH_VERIFIER = "oauth_verifier";
private FitbitAPIEntityCache entityCache = new FitbitApiEntityCacheMapImpl();
private FitbitApiCredentialsCache credentialsCache = new FitbitApiCredentialsCacheMapImpl();
private FitbitApiSubscriptionStorage subscriptionStore = new FitbitApiSubscriptionStorageInMemoryImpl();
private String apiBaseUrl;
private String fitbitSiteBaseUrl;
private String exampleBaseUrl;
private String clientConsumerKey;
private String clientSecret;
private FitbitUser fitbitUser = new FitbitUser("-");
private int year = 2012;
private int month = 5;
private int day = 5;
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
Properties properties = new Properties();
properties.load(getClass().getClassLoader().getResourceAsStream("config.properties"));
apiBaseUrl = properties.getProperty("apiBaseUrl");
fitbitSiteBaseUrl = properties.getProperty("fitbitSiteBaseUrl");
exampleBaseUrl = properties.getProperty("exampleBaseUrl").replace("/app", "");
clientConsumerKey = properties.getProperty("clientConsumerKey");
clientSecret = properties.getProperty("clientSecret");
} catch (IOException e) {
throw new ServletException("Exception during loading properties", e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
FitbitAPIClientService<FitbitApiClientAgent> apiClientService = new FitbitAPIClientService<FitbitApiClientAgent>(
new FitbitApiClientAgent(apiBaseUrl, fitbitSiteBaseUrl, credentialsCache),
clientConsumerKey,
clientSecret,
credentialsCache,
entityCache,
subscriptionStore
);
if (request.getParameter("completeAuthorization") != null) {
// Get temporary token and verifier returned by Fitbit from query string
String tempTokenReceived = request.getParameter(OAUTH_TOKEN);
String tempTokenVerifier = request.getParameter(OAUTH_VERIFIER);
// Fetch user credentials from cache by temporary token from query string
APIResourceCredentials resourceCredentials = apiClientService.getResourceCredentialsByTempToken(tempTokenReceived);
/*Handle error when there is no record of credentials in cache for the temporary token provided
As implementation of the credentials cache in this example is not persistant,
this error will popup if you restart application, while user's browser will be on Fitbit*/
if (resourceCredentials == null) {
throw new ServletException("Unrecognized temporary token when attempting to complete authorization: " + tempTokenReceived);
}
// Call method of Fitbit4J to get token credentials only if necessary (they haven't been cached yet)
if (!resourceCredentials.isAuthorized()) {
resourceCredentials.setTempTokenVerifier(tempTokenVerifier); // The verifier token is required in the request to get token credentials
try {
apiClientService.getTokenCredentials(new LocalUserDetail(resourceCredentials.getLocalUserId())); // get token credentials for user
} catch (FitbitAPIException e) {
throw new ServletException("Unable to finish authorization with Fitbit.", e);
}
}
try {
// get UserInfo
UserInfo userInfo = apiClientService.getClient().getUserInfo(new LocalUserDetail(resourceCredentials.getLocalUserId()));
request.setAttribute("userInfo", userInfo);
//get HeartRate
Heart heartInfo = apiClientService.getClient().getLoggedHeartRate(new LocalUserDetail(resourceCredentials.getLocalUserId()), fitbitUser, new LocalDate(year,month,day));
//HeartRate heartAverage = new HeartRate(heartInfo.getTrackerAverage());
request.setAttribute("heartRate", heartInfo);
/*double weight = apiClientService.getClient().getWeight(new LocalUserDetail(resourceCredentials.getLocalUserId()), new FitbitUser("-"), new LocalDate(2012,5,5));
request.setAttribute("weight", weight);*/
// get BodyInfo (weight, fat, bmi)
Body bodyInfo = apiClientService.getClient().getBody(new LocalUserDetail(resourceCredentials.getLocalUserId()), fitbitUser, new LocalDate(year,month,day));
//BodyWithGoals bodyGoals = apiClientService.getClient().getBodyWithGoals(new LocalUserDetail(resourceCredentials.getLocalUserId()), new FitbitUser("-"), new LocalDate(year,month,day));
request.setAttribute("bodyInfo", bodyInfo);
// get BloodPressure (BP) Info
Bp bloodPressureInfo = apiClientService.getClient().getLoggedBp(new LocalUserDetail(resourceCredentials.getLocalUserId()), fitbitUser, new LocalDate(year,month,day));
request.setAttribute("bloodPressureInfo", bloodPressureInfo);
// forward result to .jsp page
request.getRequestDispatcher("/fitbitApiAuthExample.jsp").forward(request, response);
} catch (FitbitAPIException e) {
throw new ServletException("Exception during getting user info", e);
}
} else {
try {
response.sendRedirect(apiClientService.getResourceOwnerAuthorizationURL(new LocalUserDetail("-"), exampleBaseUrl + "/fitbitApiAuthExample?completeAuthorization="));
} catch (FitbitAPIException e) {
throw new ServletException("Exception during performing authorization", e);
}
}
}
}