Volley in Android not attempting to connect - java

I've been attempting to get Volley to request data from the internet. Code is below. Forgive the verbose code, this was as quick and dirty test just to see if Volley worked. I'll clean it up once I get it working.
public static Option parseJSON(Context context, String stockTicker, String strikePrice, String expiration) {
final String apikey = "XXXX"; **//key removed just for StackOverflow, but it works**
String ticker = "&symbol=";
final String baseURL = "https://api.tdameritrade.com/v1/marketdata/quotes?";
Option option = new Option();
try {
SimpleDateFormat simpleDate = new SimpleDateFormat("MM/dd/yyyy");
SimpleDateFormat simpleDateforRequest = new SimpleDateFormat("MMddyy");
String formattedDate = simpleDateforRequest.format(simpleDate.parse(expiration));
String fullTicker = stockTicker + "_" + formattedDate + "C" + strikePrice;
ticker = ticker + fullTicker;
} catch (ParseException e) {
e.printStackTrace();
}
final String url = baseURL + apikey + ticker;
RequestQueue queue = Volley.newRequestQueue(context);
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
String jsonObject = response.toString();
Log.d("JSONRequestResponse", "Response: " + jsonObject);
}
}, error -> Log.d("JSONRequestResponse", "Error: " + error.toString()));
queue.add(request);
Log.d("JSON", "Request" + request + " URL: " + url);
return option; **//method doesn't create an option yet, but the problem comes well before this.**
}
The problem is that none of the logd within JsonArrayRequest are triggered and the one at the end is just an empty array ("[]"), making me think that Volley isn't attempting to connect.
I've tried using JsonObjectRequest and StringRequest as well
I've already added '<uses-permission android:name="android.permission.INTERNET'/> to the manifest, as well as trying "ACCESS_NETWORK_STATE"
The final URL works. I clicked it for the final logd and it takes me to a JSON page with the right info
The gradle version is 1.2.1, so it should be the most up-to-date
Again, I'm just testing to see if Volley retrieves a JSON, I haven't gotten to the return Object yet. At this point, I have no idea what it can be. Any help is much appreciated
UPDATE*************************************
As expected, it doesn't seem like the app is connecting to the internet. I've used this following method to see if there is a connect and it returns false:
public static boolean isNetworkAvailable() {
Log.d("CheckPoint", "isNetworkAvailable first line");
final boolean[] availability = {false};
new Thread(new Runnable() {
#Override
public void run() {
try {
availability[0] = InetAddress.getByName("www.google.com").isReachable(5000);
} catch (UnknownHostException e) {
Log.d("CheckPoint", "isNetworkAvailable UnknownHost!");
} catch (IOException e) {
Log.d("CheckPoint", "isNetworkAvailable IOException!");
}
}
}).start();
Log.d("CheckPoint", "Availability: " + availability[0]);
return availability[0];
}

You never called
requestQueue.start()
Although I have to say- unless your really need some feature that only Volley gives you, Retrofit is a much easier to use library, and it avoids some problems with Volley (Volley can cause memory issues with large responses or multiple outstanding requests because it needs to hold the entire response as an in memory String, rather than streaming it to a temp file).

Related

Java Servlet Method Parameters, response, and thread safety

I have written some REST APIs using Java Servlets on Tomcat. These are my first experiences with Java and APIs and Tomcat. As I research and read about servlets, methods and parameter passing, and more recently thread safety, I realize I need some review, suggestions, and tutorial guidance from those of you who I see are far more experienced. I have found many questions / answers that seem to address pieces but my lack of experience clouds the clarity I desire.
The code below shows the top portion of one servlet example along with an example private method. I have "global" variables defined at the class level so that I may track the success of a method and determine if I need to send an error response. I do this because the method(s) already return a value.
Are those global variables creating an unsafe thread environment
Since the response is not visible in the private methods, how else might I determine the need to stop the process and send an error response if those global variables are unsafe
Though clipped for space, should I be doing all of the XML handling in the doGet method
Should I be calling all of the different private methods for the various data retrieval tasks and data handling
Should each method that accesses the same database open a Connection or should the doGet method create a Connection and pass it to each method
Assist, suggest, teach, guide to whatever you feel appropriate, or point me to the right learning resources so I may learn how to do better. Direct and constructive criticism welcome -- bashing and derogatory statements not preferred.
#WebServlet(name = "SubPlans", urlPatterns = {"*omitted*"})
public class SubPlans extends HttpServlet {
private transient ServletConfig servletConfig;
private String planSpecialNotes,
planAddlReqLinks,
legalTermsHeader,
legalTermsMemo,
httpReturnMsg;
private String[] subPlanInd = new String[4];
private boolean sc200;
private int httpReturnStatus;
private static final long serialVersionUID = 1L;
{
httpReturnStatus = 0;
httpReturnMsg = "";
sc200 = true;
planAddlReqLinks = null;
planSpecialNotes = null;
legalTermsHeader = "";
legalTermsMemo = null;
}
#Override
public void init(ServletConfig servletConfig)
throws ServletException {
this.servletConfig = servletConfig;
}
#Override
public ServletConfig getServletConfig() {
return servletConfig;
}
#Override
public String getServletInfo() {
return "SubPlans";
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<HashMap<String, Object>> alSubDeps = new ArrayList<HashMap<String, Object>>();
String[] coverageDates = new String[6],
depDates = new String[8];
String eeAltId = null,
eeSSN = null,
carrier = null,
logosite = null,
fmtSSN = "X",
subSQL = null,
healthPlan = null,
dentalPlan = null,
visionPlan = null,
lifePlan = null,
tier = null,
healthGroupNum = null,
effdate = null,
holdEffDate = null,
planDesc = "",
planYear = "",
summaryBenefitsLink = null;
int[][] effdates = new int[6][4];
int holdDistrictNumber = 0,
districtNumber = 0,
holdUnit = 0,
unit = 0;
boolean districtHasHSA = false;
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
try {
eeAltId = request.getParameter("*omitted*");
if ( eeAltId != null ) {
Pattern p = Pattern.compile(*omitted*);
Matcher m = p.matcher(eeAltId);
if ( m.find(0) ) {
eeSSN = getSSN(eeAltId);
} else {
httpReturnStatus = 412;
httpReturnMsg = "Alternate ID format incorrect.";
System.err.println("Bad alternate id format " + eeAltId);
sc200 = false;
}
} else {
httpReturnStatus = 412;
httpReturnMsg = "Alternate ID missing.";
System.err.println("alternate id not provided.");
sc200 = false;
}
if ( sc200 ) {
coverageDates = determineDates();
subSQL = buildSubSQLStatement(eeSSN, coverageDates);
alSubDeps = getSubDeps(subSQL);
if ( sc200 ) {
XMLStreamWriter writer = outputFactory.createXMLStreamWriter(response.getOutputStream());
writer.writeStartDocument("1.0");
writer.writeStartElement("subscriber");
// CLIPPED //
writer.writeEndElement(); // subscriber
writer.writeEndDocument();
if ( sc200 ) {
response.setStatus(HttpServletResponse.SC_OK);
writer.flush();
} else {
response.sendError(httpReturnStatus, httpReturnMsg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error writing XML");
System.err.println(e);
}
}
#Override
public void destroy() {
}
private String getPlanDescription(String planID) {
String planDesc = null;
String sqlEE = "SELECT ...";
Connection connGPD = null;
Statement stGPD = null;
ResultSet rsGPD = null;
try {
connGPD = getDbConnectionEE();
try {
stGPD = connGPD.createStatement();
planDesc = "Statement error";
try {
rsGPD = stGPD.executeQuery(sqlEE);
if ( !rsGPD.isBeforeFirst() )
planDesc = "No data";
else {
rsGPD.next();
planDesc = rsGPD.getString("Plan_Description");
}
} catch (Exception rsErr) {
httpReturnStatus = 500;
httpReturnMsg = "Error retrieving plan description.";
System.err.println("getPlanDescription: " + httpReturnMsg + " " + httpReturnStatus);
System.err.println(rsErr);
sc200 = false;
} finally {
if ( rsGPD != null ) {
try {
rsGPD.close();
} catch (Exception rsErr) {
System.err.println("getPlanDescription: Error closing result set.");
System.err.println(rsErr);
}
}
}
} catch (Exception stErr) {
httpReturnStatus = 500;
httpReturnMsg = "Error creating plan description statement.";
System.err.println("getPlanDescription: " + httpReturnMsg + " " + httpReturnStatus);
System.err.println(stErr);
sc200 = false;
} finally {
if ( stGPD != null ) {
try {
stGPD.close();
} catch (Exception stErr) {
System.err.println("getPlanDescription: Error closing query statement.");
System.err.println(stErr);
}
}
}
} catch (Exception connErr) {
httpReturnStatus = 500;
httpReturnMsg = "Error closing database.";
System.err.println("getPlanDescription: " + httpReturnMsg + " " + httpReturnStatus);
System.err.println(connErr);
sc200 = false;
} finally {
if ( connGPD != null ) {
try {
connGPD.close();
} catch (Exception connErr) {
System.err.println("getPlanDescription: Error closing connection.");
System.err.println(connErr);
}
}
}
return planDesc.trim();
}
I have "global" variables defined at the class level
You have instance variables declared at the class level. There are no globals in Java.
so that I may track the success of a method and determine if I need to send an error response.
Poor technique.
I do this because the method(s) already return a value.
You should use exceptions for this if the return values are already taken.
Are those global variables creating an unsafe thread environment
Those instance variables are creating an unsafe thread environment.
Since the response is not visible in the private methods, how else might I determine the need to stop the process and send an error response if those global variables are unsafe?
Via exceptions thrown by the methods, see above. If there is no exception, send an OK response, whatever form that takes, otherwise whatever error response is appropriate to the exception.
Though clipped for space, should I be doing all of the XML handling in the doGet method
Not if it's long or repetitive (used in other places too).
Should I be calling all of the different private methods for the various data retrieval tasks and data handling
Sure, why not?
Should each method that accesses the same database open a Connection or should the doGet() method create a Connection and pass it to each method
doGet() should open the connection, pass it to each method, and infallibly close it.
NB You don't need the ServletConfig variable, or the init() or getServletConfig() methods. If you remove all this you can get it from the base class any time you need it via the getServletConfig() method you have pointlessly overridden.
The variables you have defined are instance members. They are not global and are not class-level. They are variables scoped to one instance of your servlet class.
The servlet container typically creates one instance of your servlet and sends all requests to that one instance. So you will have concurrent requests overwriting these variables’ contents unpredictably.
It can be ok for a servlet to have static variables or instance member variables, but only if their contents are thread safe and they contain no state specific to a request. For instance it would be normal to have a (log4j or java.util.logging) Logger object as a static member, where the logger is specifically designed to be called concurrently without the threads interfering with each other.
For error handling use exceptions to fail fast once something goes wrong.
Servlets are painful to write and hard to test. Consider using a MVC web framework instead. Frameworks like spring or dropwizard provide built-in capabilities that make things like data access and error handling easier, but most importantly they encourage patterns where you write separate well-focused classes that each do one thing well (and can be reasoned about and tested independently). The servlet approach tends to lead people to cram disparate functions into one increasingly-unmanageable class file, which seems to be the road you’re headed down.

How to parse DFT_P03 message with ZPM segment

I am coding a server application that will receive DFT_P03 messages with an added ZPM segment (which i have created a class for as per the HAPI documentation). Currently i am able to access this field as a generic segment when doing the following :
#Override
public Message processMessage(Message t, Map map) throws ReceivingApplicationException, HL7Exception
{
String encodedMessage = new DefaultHapiContext().getPipeParser().encode(t);
logEntryService.logDebug(LogEntry.CONNECTIVITY, "Received message:\n" + encodedMessage + "\n\n");
try
{
InboundMessage inboundMessage = new InboundMessage();
inboundMessage.setMessageTime(new Date());
inboundMessage.setMessageType("Usage");
DFT_P03 usageMessage = (DFT_P03) t;
Segment ZPMSegment = (Segment)usageMessage.get("ZPM");
inboundMessage.setMessage(usageMessage.toString());
Facility facility = facilityService.findByCode(usageMessage.getMSH().getReceivingFacility().getNamespaceID().getValue());
inboundMessage.setTargetFacility(facility);
String controlID = usageMessage.getMSH().getMessageControlID().encode();
controlID = controlID.substring(controlID.indexOf("^") + 1, controlID.length());
inboundMessage.setControlId(controlID);
Message response;
try
{
inboundMessageService.save(inboundMessage);
response = t.generateACK();
logEntryService.logDebug(LogEntry.CONNECTIVITY, "Message ACKed");
}
catch (Exception ex)
{
response = t.generateACK(AcknowledgmentCode.AE, new HL7Exception(ex));
logEntryService.logDebug(LogEntry.CONNECTIVITY, "Message NACKed");
}
return response;
}
catch (IOException e)
{
logEntryService.logDebug(LogEntry.CONNECTIVITY, "Message rejected");
throw new HL7Exception(e);
}
}
I have created a DFT_P03_Custom class as following :
public class DFT_P03_Custom extends DFT_P03
{
public DFT_P03_Custom() throws HL7Exception
{
this(new DefaultModelClassFactory());
}
public DFT_P03_Custom(ModelClassFactory factory) throws HL7Exception
{
super(factory);
String[] segmentNames = getNames();
int indexOfPid = Arrays.asList(segmentNames).indexOf("FT1");
int index = indexOfPid + 1;
Class<ZPM> type = ZPM.class;
boolean required = true;
boolean repeating = false;
this.add(type, required, repeating, index);
}
public ZPM getZPM()
{
return getTyped("ZPM", ZPM.class);
}
}
When trying to typecast the message to a DFT_P03_Custom instance i get a ClassCastException. As per their documentation, i did create the CustomModelClassFactory class but using this i just get tons of validation errors on the controlId field.
I am already using an identical logic to send custom MFN_M01 messages with an added ZFX segment and that works flawlessly. I understand there is some automatic typecasting being done by HAPI when it receives a DFT_P03 message and that is likely what i need to somehow override for it to be able to give me a DFT_P03_Custom instance instead.
If you have some insight on how i can achieve this without having to use a generic segment instance please help!
Thank you!
I finally figured this out. The only way i got this to work was to generate a conformance profile XML file (using an example message from our application as a base) with the messaging workbench on the HAPI site and use the maven plugin to generate the message and segment classes. Only with these classes am i able to correctly parse a message to my custom class. One thing to note is that it DOES NOT work if i try to use the MSH, PID, PV1 or FT1 classes provided by HAPI and use my Z-segment class. It only works if all the segments are the classes generated by the conformance plugin. This combined with a CustomModelClassFactory class (as shown on the HAPI website) and the proper package structure finally allowed me to access my Z-segment.

How to use Authentication with JIRA REST API in Java

hi im creating a simple tool using java to create,update and delete issues(tickets) in jira. i am using rest api following code is im using to authenticate jira and issue tickets.
public class JiraConnection {
public static URI jiraServerUri = URI.create("http://localhost:8090/jira/rest/api/2/issue/HSP-1/");
public static void main(String args[]) throws IOException {
final AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
final JiraRestClient restClient = factory.createWithBasicHttpAuthentication(jiraServerUri,"vinuvish92#gmail.com","vinu1994");
System.out.println("Sending issue creation requests...");
try {
final List<Promise<BasicIssue>> promises = Lists.newArrayList();
final IssueRestClient issueClient = restClient.getIssueClient();
System.out.println("Sending issue creation requests...");
for (int i = 0; i < 100; i++) {
final String summary = "NewIssue#" + i;
final IssueInput newIssue = new IssueInputBuilder("TST", 1L, summary).build();
System.out.println("\tCreating: " + summary);
promises.add(issueClient.createIssue(newIssue));
}
System.out.println("Collecting responses...");
final Iterable<BasicIssue> createdIssues = transform(promises, new Function<Promise<BasicIssue>, BasicIssue>() {
#Override
public BasicIssue apply(Promise<BasicIssue> promise) {
return promise.claim();
}
});
System.out.println("Created issues:\n" + Joiner.on("\n").join(createdIssues));
} finally {
restClient.close();
}
}
}
according this code i couldn't connect to the jira
**following exception i am getting **
please suggest me best solution to do my task
It seems to me that your error is clearly related to url parameter. The incriminated line and the fact that the error message is about not finding the resource are good indications of it.
You don't need to input the whole endpoint since you are using the JiraRestClient. Depending on the method that you call it will resolve the endpoint. Here is an example that works: as you can see I only input the base url

java jira rest client timeout issue

I get java.net.SocketTimeoutException when searching in jira. How can I increase the timeout ?
Code:
JiraRestClientFactory restClientFactory = new AsynchronousJiraRestClientFactory();
SearchResult results = null;
try {
URI uri = new URI(jira_url);
restClient = restClientFactory.createWithBasicHttpAuthentication(uri, jira_username, jira_password);
final SearchRestClient searchClient = restClient.getSearchClient();
String jql = searchClient.getFilter(jira_filterid).get().getJql();
// setting max result to 1000 and start with 0
results = searchClient.searchJql(jql, 500, 0).claim();
System.out.println("Took: " + stopWatch.toString() + " to find " + results.getTotal() + " case in jira filter with id " + jira_filterid);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return results;
The searching should not take so long, i think it is when doing claim().
Exception:
java.lang.RuntimeException: java.net.SocketTimeoutException
at com.google.common.base.Throwables.propagate(Throwables.java:160)
at com.atlassian.httpclient.apache.httpcomponents.DefaultHttpClient$3.apply(DefaultHttpClient.java:256)
at com.atlassian.httpclient.apache.httpcomponents.DefaultHttpClient$3.apply(DefaultHttpClient.java:249)
at com.atlassian.util.concurrent.Promises$Of$2.apply(Promises.java:276)
at com.atlassian.util.concurrent.Promises$Of$2.apply(Promises.java:272)
at com.atlassian.util.concurrent.Promises$2.onFailure(Promises.java:167)
at com.google.common.util.concurrent.Futures$4.run(Futures.java:1172)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:202)
at com.google.common.util.concurrent.SettableFuture.setException(SettableFuture.java:68)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$1$2.run(SettableFuturePromiseHttpPromiseAsyncClient.java:59)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$ThreadLocalDelegateRunnable$1.run(SettableFuturePromiseHttpPromiseAsyncClient.java:197)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient.runInContext(SettableFuturePromiseHttpPromiseAsyncClient.java:90)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$ThreadLocalDelegateRunnable.run(SettableFuturePromiseHttpPromiseAsyncClient.java:192)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.net.SocketTimeoutException
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:279)
at org.apache.http.impl.nio.client.LoggingAsyncRequestExecutor.timeout(LoggingAsyncRequestExecutor.java:128)
at org.apache.http.impl.nio.DefaultHttpClientIODispatch.onTimeout(DefaultHttpClientIODispatch.java:136)
at org.apache.http.impl.nio.DefaultHttpClientIODispatch.onTimeout(DefaultHttpClientIODispatch.java:50)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:169)
at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:257)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:494)
at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:207)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:284)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:604)
... 1 more
I can not Believe i had to got so deep to change it. you can use reflection to achieve it
try (JiraRestClient client = clientFactory.createWithBasicHttpAuthentication(new URI(jira.getUrl()), jira.getUsername(), jira.getPassword())) {
try {
Field f1 = Class.forName("com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClient").getDeclaredField("httpClient");
Field f2 = Class.forName("com.atlassian.jira.rest.client.internal.async.AtlassianHttpClientDecorator").getDeclaredField("httpClient");
Field f3 = Class.forName("com.atlassian.httpclient.apache.httpcomponents.ApacheAsyncHttpClient").getDeclaredField("httpClient");
Field f4 = Class.forName("org.apache.http.impl.client.cache.CachingHttpAsyncClient").getDeclaredField("backend");
Field f5 = Class.forName("org.apache.http.impl.nio.client.InternalHttpAsyncClient").getDeclaredField("defaultConfig");
Field f6 = Class.forName("org.apache.http.client.config.RequestConfig").getDeclaredField("socketTimeout");
f1.setAccessible(true);
f2.setAccessible(true);
f3.setAccessible(true);
f4.setAccessible(true);
f5.setAccessible(true);
f6.setAccessible(true);
Object requestConfig = f5.get(f4.get(f3.get(f2.get(f1.get(client)))));
f6.setInt(requestConfig, 120 * 1000);
f1.setAccessible(false);
f2.setAccessible(false);
f3.setAccessible(false);
f4.setAccessible(false);
f5.setAccessible(false);
f6.setAccessible(false);
} catch (Exception ignore) {
}
// now you can start using it :)
} catch (URISyntaxException | IOException e) {
logger.error("invalid jira server address: " + jira.getUrl(), e);
throw new RuntimeException("can not access jira server");
}
it will buy you 120 seconds of socket time.
one workaround that seams to work is to take 100 result for each iteration and set startAt
results = searchClient.searchJql(jql, 100, 0).claim();
results1 = searchClient.searchJql(jql, 100, 100).claim();
results2 = searchClient.searchJql(jql, 100, 200).claim();
and so on.
Disclaimer: i am using the Groovy programming language, but the syntax is very similar to Java, so you should be able to reuse the code (hint: in Groovy no semi-colons are needed, the return statement is optional, instead of variable declaration i am using def or final only).
I am using the following library versions (gradle style):
compile "com.atlassian.jira:jira-rest-java-client-core:4.0.0"
compile "com.atlassian.fugue:fugue:2.2.1"
Here we have the standard rest client definition:
JiraRestClient getJiraRestClient()
{
// read user specific Jira password settings and build authentification
final inputFile = new File("${System.getProperty('user.home')}/jiraSettings.json")
final authInfo = new JsonSlurper().parseText(inputFile.text)
// setting up the jira client
def restClient = new AsynchronousJiraRestClientFactory()
.createWithBasicHttpAuthentication(
jiraServerUri,
authInfo.jiraUser.toString(),
authInfo.jiraPassword.toString())
restClient
}
I dived into the createWithBasicHttpAuthentication function and extracted and adapted the code (only getClientOptions - I set the socket timeout to 45 seconds, look at HttpClientOptions default settings):
JiraRestClient getJiraRestClient()
{
return new AsynchronousJiraRestClient(jiraServerUri, getHttpClient());
}
HttpClientOptions getClientOptions()
{
def options = new HttpClientOptions();
options.socketTimeout = 45000L;
options
}
DisposableHttpClient getHttpClient()
{
final DefaultHttpClientFactory defaultHttpClientFactory =
new DefaultHttpClientFactory(new AsynchronousHttpClientFactory.NoOpEventPublisher(),
new AsynchronousHttpClientFactory.RestClientApplicationProperties(jiraServerUri),
new ThreadLocalContextManager() {
#Override
public Object getThreadLocalContext() {
return null;
}
#Override
public void setThreadLocalContext(Object context) {}
#Override
public void clearThreadLocalContext() {}
});
final HttpClient httpClient = defaultHttpClientFactory.create(getClientOptions())
return new AtlassianHttpClientDecorator(httpClient, getAuthenticationHandler()) {
#Override
public void destroy() throws Exception {
defaultHttpClientFactory.dispose(httpClient);
}
}
}
BasicHttpAuthenticationHandler getAuthenticationHandler()
{
// read user specific Jira password settings and build authentification
final inputFile = new File("${System.getProperty('user.home')}/jiraSettings.json")
final authInfo = new JsonSlurper().parseText(inputFile.text)
return new BasicHttpAuthenticationHandler(
authInfo.jiraUser.toString(),
authInfo.jiraPassword.toString())
}
The downside is that I might be forced to adapt this code when I switch to a new version of jira-rest-java-client, but I really need this because the timout is just to short, even with heavy use of paging.
java.util.concurrent.Future class has V get(long timeout, TimeUnit unit).
Adding timeout helped me:
String jql = searchClient.getFilter(jira_filterid).get(120, TimeUnit.SECONDS).getJql();

Restlet Android client - How to map JSON response from ASP.NET Web API to my Java Objects

I'm kinda having trouble understand how to make the best and map my JASON response from an ASP.NET Web API server into my Java classes.
I use this code to request the server data.
ClientResource res = new ClientResource(ADDRESS_URL + "/exed/students/");
Representation rep = res.get();
try {
Log.d(TAG, rep.getText());
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
I successfuly can retrieve this JSON representation.
{"$id":"1","StudentId":1,"RowVersion":"AAAAAAAAB9M=","User":{"$id":"2","UserId":1,"Username":"1","Password":"1","UserTypeId":1,"FirstName":"George","LastName":"Taskos","RowVersion":"AAAAAAAAB9I=","Student":{"$ref":"1"},"Teacher":null,"UserType":null}}
Now I have these Java classes.
The User.
public class User implements Serializable {
// Private fields
//
private int userId;
private String username;
private String password;
private int userTypeId;
private String firstName;
private String lastName;
private String userType;
private Timestamp rowVersion;
// Setters
// Getters....
}
And the Student.
public class Student extends User implements Serializable {
// Private fields
private List<ClassType> classes;
private List<ExamTaken> examsTaken;
private Timestamp rowVersionStudent;
}
How to retrieve the representation into my objects. I've seen so much and I think I'm so dizzy right now to get a solution.
I'm not familiar with Java server side or anything so I guess thats why I get frustrated about stuff I read on the tutorials and I think lots of stuff missing from the site, or not clearly explained.
Any simple example at least on get the values out and get them into my object like I do with SQLite cursors.
Deserialization from response would be really great too :)
[EDIT]
After Raw suggestion I ended up with this code.
ClientResource res = new ClientResource(ADDRESS_URL + "/exed/students/");
Representation rep = res.get();
try {
JSONObject response = new JSONObject(rep.getText());
Log.d(TAG, rep.getText());
JSONObject user = response.getJSONObject("User");
Log.d(TAG, "User: " + user.toString());
JSONObject student = response.getJSONObject("Student");
Log.d(TAG, "Student: " + student.toString());
Log.d(TAG, "FirstName: " + user.getString("FirstName"));
} catch (Exception e) {
Log.d(TAG, "Exception: " + e.getMessage());
}
But getting an Exception with this message: Exception: println needs a message
Stacktrace prints this: Exception: android.util.Log.println_native(Native Method)
and the unhandled exception is this:
03-06 13:07:14.668: ERROR/AndroidRuntime(25353): FATAL EXCEPTION: Thread-13908
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:155)
at com.tech.ed.data.access.WebServiceRepository$1.run(WebServiceRepository.java:74)
at java.lang.Thread.run(Thread.java:856)
I don't exactly understand what it means!
Thank you.
Looks like you just have a series of JSONObjects and strings. Just make one JSONObject for the entire results
JSONObject response = new JSONObject(representation);
then extract out the user and student objects
JSONObject user = response.getJSONObject("User");
JSONObject student = response.getJSONObject("Student");
Then you can get any nested strings, ints or whatever from the corresponding objects with something like
String firstName = user.getString("FirstName");

Categories

Resources