Extracting data from Json object by http GET - java

I am working on android app and I want to know how to get data from Json object by using http GET the (the http request url is APIary)
It's my first time to use Json and httpRequests so I don't know the syntax needed for this
That's my HttpRequest class I'm using :
public abstract class HttpRequest extends AsyncTask<String, String, String> {
private HttpClient httpClient;
private HttpRequestBase request;
private boolean hasError = false;
private String errorMessage = null;
private boolean hasBody = false;
private int statusCode;
public HttpRequest(){
httpClient = new DefaultHttpClient();
}
/**
* This method is called from the subclasses to pass the request method used to this class
* #param request , The request class passed from the subclass
*/
void setMethod(HttpRequestBase request){
this.request = request;
}
/**
* Adds a header to the current request
* #param header , header key
* #param value , header value
*/
public void addHeader(String header,String value){
this.request.addHeader(header, value);
}
/**
* #return false if the status code was anything other than 2XX after executing the request , true otherwise
*/
public boolean hasError() {
return hasError;
}
/**
* A getter for the error message
* #return String the error message returned from the request if any
*/
public String getErrorMessage() {
return errorMessage;
}
/**
* This is the method responsible for executing the request and handling the response
* #return String , The response body , null in case of errors
*/
#Override
protected String doInBackground(String... args) {
if(hasBody){
this.request.addHeader("content-type", "application/json");
}
ResponseHandler<String> handler = new BasicResponseHandler();
HttpResponse x = null;
try{
x = httpClient.execute(this.request);
this.statusCode = x.getStatusLine().getStatusCode();
return handler.handleResponse(x);
}catch(ClientProtocolException e ){
hasError = true;
errorMessage = e.getMessage();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* A getter method for the status code
* #return int , the status code of executing the request
*/
public int getStatusCode(){
return this.statusCode;
}
/**
* A setter method to set whether the request has a body or not , used between this class and its subclasses
* #param hasBody boolean
*/
void setHasBody(boolean hasBody){
this.hasBody = hasBody;
}
}

I think this post can help you :
How to parse JSON in Android
Tell me if don't understand !

Related

How to mock HttpClient using Mockito

This is my Actual class for which i am writing junit. I have HtpClient as private and final.
public class KMSHttpClientImpl implements KMSHttpClient
{
/**
* ObjectMapper Instance.
*/
private final ObjectMapper objectMapper = new ObjectMapper ();
/**
* KMS ConnectionManager Instance.
*/
private final KMSHttpConnectionManager kmsHttpConnectionManager =
new KMSHttpConnectionManagerImpl ();
/**
* HttpClient object.
*/
private final HttpClient httpClient;
/**
* KMSHttpClient constructor.
*/
public KMSHttpClientImpl ()
{
// TODO PoolingHttpClientConnectionManager object should be closed after use.
// TODO This needs to be either singleton or should be kept in static block
final PoolingHttpClientConnectionManager connectionManager =
kmsHttpConnectionManager.getConnectionManager();
httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
}
#Override
public <T> T invokeGETRequest (final String url, final Class<T> clazz)
throws KMSClientException
{
final HttpGet httpGet = new HttpGet(url);
try {
final HttpResponse response = httpClient.execute(httpGet);
return objectMapper.readValue(
response.getEntity().getContent(), clazz);
} catch (IOException e) {
throw new KMSClientException("Unable to get the result", e);
}
}
#Override
public <T> T invokePOSTRequest (final String url, final Object object, final Class<T> clazz)
throws KMSClientException
{
final HttpPost httpPost = new HttpPost(url);
try {
final HttpResponse response = httpClient.execute(httpPost);
return objectMapper.readValue(
response.getEntity().getContent(), clazz);
} catch (IOException e) {
throw new KMSClientException("Unable to create the request", e);
}
}
}
This is my testclass. I am trying to Mock HttpClient but as it is final i cant mock it. And if i remove final from HttpClient in my KMSHttpClientImpl.java class. I am getting PMd issue saying
Private field 'httpClient' could be made final; it is only initialized in the declaration or constructor. What can i do to fix this issue?
public class KMSHttpClientImplTest
{
/**
* Injecting mocks KMSHttpClientImpl.
*/
#InjectMocks
private KMSHttpClientImpl kmsHttpClientImpl;
/**
* Mock HttpClient.
*/
#Mock
private HttpClient httpClient;
/**
* Initial SetUp Method.
*/
#Before
public void setUp ()
{
initMocks(this);
}
/**
* Method to test postRequest Method.
* #throws KMSClientException
*/
#Test
public void testPostRequest () throws KMSClientException
{
final OrganizationRequest request = getOrganizationRequest();
final HttpResponse response = prepareResponse(HttpStatus.SC_OK);
try {
Mockito.when(httpClient.execute(Mockito.any())).thenReturn(response);
final OrganizationResponse organizationResponse = kmsHttpClientImpl.invokePOSTRequest(
ORG_TEST_URL, request, OrganizationResponse.class);
assertEquals("Id should match", ORG_ID, organizationResponse.getId());
} catch (IOException e) {
throw new KMSClientException("Unable to create the request", e);
}
}
/**
* Method to test getRequest Method.
* #throws KMSClientException
*/
#Test
public void testGetRequest () throws KMSClientException
{
try {
final HttpResponse response = prepareResponse(HttpStatus.SC_OK);
Mockito.when(httpClient.execute(Mockito.any())).thenReturn(response);
final OrganizationResponse organizationResponse = kmsHttpClientImpl.invokeGETRequest
(ORG_TEST_URL, OrganizationResponse.class);
assertEquals("Id should match", ORG_ID, organizationResponse.getId());
} catch (IOException e) {
throw new KMSClientException("Unable to create the request", e);
}
}
/**
* Method to organizationRequest Object.
* #return OrganizationRequest object
*/
public OrganizationRequest getOrganizationRequest ()
{
return OrganizationRequest.builder().id("test").build();
}
/**
* Method to getOrganizationResponse String.
* #return String Object
*/
public String getOrganizationResponse ()
{
final Map obj=new HashMap();
obj.put("id", ORG_ID);
obj.put("uuid", ORG_UUID);
obj.put("orgKeyId", ORG_KEYID);
return JSONValue.toJSONString(obj);
}
/**
* Method to prepare Response.
* #param expectedResponseStatus
* #return HttpResponse
*/
private HttpResponse prepareResponse (final int expectedResponseStatus)
{
final HttpResponse response = new BasicHttpResponse(new BasicStatusLine(
new ProtocolVersion("HTTP", 1, 1),
expectedResponseStatus, ""));
response.setStatusCode(expectedResponseStatus);
final HttpEntity httpEntity = new StringEntity(getOrganizationResponse(),
ContentType.APPLICATION_JSON);
response.setEntity(httpEntity);
return response;
}
}
One of the ways to test a HTTP client code would be to not mock your HTTPClient object, but to create mock responses for the http calls and then let your HPPTClient make calls to those URLs.
Take a look at Wiremock. http://wiremock.org/docs/
It helps you create a simple mock server and you can stub responses for your URLs.
Then invoke your URLs using your client for the test.
A simple way to use a mocked HttpClient for your tests is to add a second constructor that takes a HttpClient.
public class KMSHttpClientImpl implements KMSHttpClient
{
private final HttpClient httpClient;
public KMSHttpClientImpl ()
{
final PoolingHttpClientConnectionManager connectionManager =
kmsHttpConnectionManager.getConnectionManager();
httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
}
// This constructor is package private instead
// of public so it is not accidentally used by
// classes outside of this package. If your test
// class is not in the same package, then you
// need to make this a public constructor.
KMSHttpClientImpl (final HttpClient httpClient)
{
this.httpClient = httpClient;
}
}
You then inject your mocked HttpClient using this constructor and will need neither #InjectMocks nor #Mock in your tests.
#Test
public void testPostRequest () throws KMSClientException
{
final HttpClient httpClient = Mockito.mock(HttpClient.class);
final HttpResponse response = prepareResponse(HttpStatus.SC_OK);
Mockito.when(httpClient.execute(Mockito.any())).thenReturn(response);
final KMSHttpClientImpl kmsHttpClientImpl = new KMSHttpClientImpl(httpClient);
// run your test...
}
You can't mock a final instance using plain mocking. You need something like PowerMock.
See the answer to this questionfor implementation.

Spring form input values return null after read it once in filter, despite using request wrapper

In my spring-boot project, I use freemarker templates for sample forms. I needed to add filter in order to read payload and do some stuff. I know if you read payload in filter, you need to reset request body. Because it can be read once. Since I encountered this problem before, I knew that I must have used wrapper. I expected solve my problem as before. However, in the controller, all fields in input objects are null.
What am I missing in here ?
My filter:
public class KfsInMsgFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
Map<String, String[]> extraParams = new TreeMap<String, String[]>();
WrappedRequest wrappedRequest = new WrappedRequest(request, extraParams);
String body = IOUtils.toString(new BufferedReader(new InputStreamReader(wrappedRequest.getInputStream(), Constants.UTF_8)));
// doing some stuff using body
// ....
// resetting payload
wrappedRequest.resetStream(body.getBytes(Constants.UTF_8));
...
}
}
WrappedRequest class:
#Slf4j
public class WrappedRequest extends HttpServletRequestWrapper {
private final Map<String, String[]> modifiableParameters;
private ResettableServletInputStream servletStream;
private byte[] rawData;
private HttpServletRequest request;
private String payload;
/**
* Create a new request wrapper that will merge additional parameters into
* the request object without prematurely reading parameters from the
* original request.
*
* #param request
* #param additionalParams
*/
public WrappedRequest(final HttpServletRequest request,
final Map<String, String[]> additionalParams) {
super(request);
this.request = request;
this.modifiableParameters = new TreeMap<String, String[]>();
this.modifiableParameters.putAll(additionalParams);
this.servletStream = new ResettableServletInputStream();
}
/**
* #param newRawData
*/
public void resetStream(byte[] newRawData) {
servletStream.stream = new ByteArrayInputStream(newRawData);
}
/**
* #return
* #throws IOException
*/
#Override
public ServletInputStream getInputStream() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getReader());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return servletStream;
}
/**
* #return
* #throws IOException
*/
#Override
public BufferedReader getReader() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getReader());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return new BufferedReader(new InputStreamReader(servletStream, Constants.UTF_8));
}
/**
* #return
*/
private String getBodyAsString() {
StringBuffer buff = new StringBuffer();
buff.append(" BODY_DATA START [ ");
char[] charArr = new char[getContentLength()];
try {
BufferedReader reader = new BufferedReader(getReader());
reader.read(charArr, 0, charArr.length);
reader.close();
} catch (IOException e) {
log.error("", e);
}
buff.append(charArr);
buff.append(" ] BODY_DATA END ");
return buff.toString();
}
/**
* #return
*/
public String getPayload() {
return payload;
}
/**
* #param payload
*/
public void setPayload(String payload) {
this.payload = payload;
}
private static class ResettableServletInputStream extends ServletInputStream {
private InputStream stream;
#Override
public int read() throws IOException {
return stream.read();
}
#Override
public boolean isFinished() {
return false;
}
#Override
public boolean isReady() {
return false;
}
#Override
public void setReadListener(ReadListener readListener) {
}
}
}
Body I expected to get in controller:
What I get:
#PostMapping(value = "/edit")
public String editPlatform(EditInfo editInfo, Model model) {
Optional<Platform> p = platformService.findById(editInfo.getId());
List<SafeCustodyOffice> officeList = safeCustodyOfficeService.getAll();
if (p.isPresent()) {
model.addAttribute("platform", p.get());
model.addAttribute("offices", officeList);
return "platform-edit";
} else {
throw new KfsException(ErrorCodes.KFS19);
}
}
Important Edit:
I discovered someting I found interesting and gives me clues about the problem. This may be makes more sense for anybody but me.
I see that the content type of input changes the result like this:
Is there any workaround to make row 5 combination work like row 3?

HttpServletRequestWrapper lose multipart inputs values

I'm trying to develop a XSS Filter. All works fine, but the wrapper is losing the multipart fields.
After the filter, in the controller, when I try to obtain the value of a multipart field always is empty.
I have the following wrapper:
public class XSSRequestWrapperMultipart extends HttpServletRequestWrapper {
/** Constructor. */
public XSSRequestWrapperMultipart(HttpServletRequest aRequest) throws IOException {
super(aRequest);
ServletFileUpload upload = new ServletFileUpload( new DiskFileItemFactory());
try {
List<FileItem> fileItems = upload.parseRequest(aRequest);
convertToMaps(fileItems);
}
catch(FileUploadException ex){
throw new IOException("Cannot parse underlying request: " + ex.toString());
}
}
/**
* Return all request parameter names, for both regular controls and file upload
* controls.
*/
#Override public Enumeration<String> getParameterNames() {
Set<String> allNames = new LinkedHashSet<>();
allNames.addAll(fRegularParams.keySet());
allNames.addAll(fFileParams.keySet());
return Collections.enumeration(allNames);
}
/**
* Return the parameter value. Applies only to regular parameters, not to
* file upload parameters.
*/
#Override public String getParameter(String aName) {
String result = null;
List<String> values = fRegularParams.get(aName);
if(values == null){
//you might try the wrappee, to see if it has a value
}
else if (values.isEmpty()) {
//param name known, but no values present
result = "";
}
else {
//return first value in list
result = values.get(FIRST_VALUE);
}
return result;
}
/**
* Return the parameter values. Applies only to regular parameters,
* not to file upload parameters.
*/
#Override public String[] getParameterValues(String aName) {
String[] result = null;
List<String> values = fRegularParams.get(aName);
if(values != null) {
result = values.toArray(new String[values.size()]);
}
return result;
}
/**
* Return a {#code Map<String, List<String>>} for all regular parameters.
* Does not return any file upload parameters at all.
*/
#Override public Map<String, List<String>> getParameterMap() {
return Collections.unmodifiableMap(fRegularParams);
}
/**
* Return a {#code List<FileItem>}, in the same order as they appear
* in the underlying request.
*/
public List<FileItem> getFileItems(){
return new ArrayList<FileItem>(fFileParams.values());
}
/**
* Return the {#link FileItem} of the given name.
* <P>If the name is unknown, then return <tt>null</tt>.
*/
public FileItem getFileItem(String aFieldName){
return fFileParams.get(aFieldName);
}
// PRIVATE
/** Store regular params only. May be multivalued (hence the List). */
private final Map<String, List<String>> fRegularParams = new LinkedHashMap<>();
/** Store file params only. */
private final Map<String, FileItem> fFileParams = new LinkedHashMap<>();
private static final int FIRST_VALUE = 0;
private void convertToMaps(List<FileItem> aFileItems){
for(FileItem item: aFileItems) {
if ( isFileUploadField(item) ) {
fFileParams.put(item.getFieldName(), item);
}
else {
if( alreadyHasValue(item) ){
addMultivaluedItem(item);
}
else {
addSingleValueItem(item);
}
}
}
}
private boolean isFileUploadField(FileItem aFileItem){
return ! aFileItem.isFormField();
}
private boolean alreadyHasValue(FileItem aItem){
return fRegularParams.get(aItem.getFieldName()) != null;
}
private void addSingleValueItem(FileItem aItem){
List<String> list = new ArrayList<>();
list.add(aItem.getString());
fRegularParams.put(aItem.getFieldName(), list);
}
private void addMultivaluedItem(FileItem aItem){
List<String> values = fRegularParams.get(aItem.getFieldName());
values.add(aItem.getString());
}
}
All relative to the fRegularParams works fine, but the fFileParams always appears as null in the controller.
What can I do to keep the values?
Regards
If you see for fRegularParams, you are touching the getParameter() method of servlet lifecycle.
Here the parameters are already initialized in this phase.
For fFileParams you are trying to get params in constructor, which is too early considering lifecycle of servlet and filters.
Image for your reference:
Solution:
Can you try with method request.getParts() instead?
You can try this approach and override
https://github.com/spring-projects/spring-framework/blob/2f20d6322b7a0fcbbaa80280849e7c31fc78d4a9/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java#L131
Which internally deals with request parts.
https://github.com/spring-projects/spring-framework/blob/2f20d6322b7a0fcbbaa80280849e7c31fc78d4a9/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java#L91
Here "might" be your problem:
private boolean isFileUploadField(FileItem aFileItem){
return ! aFileItem.isFormField();
}
It's returning the opposite response of the boolean value (check the !). Remove it and test if that works.
Only if the FileItem.isFormField() that you can get the form parameter data.
private boolean isFileUploadField(FileItem aFileItem){
return aFileItem.isFormField();
}

Spring RestTemplate exchange throws UnhandledHttpStatusException

Overview:
I am going to use RestTemplate to invoke a get request from external REST webservice.
My code is as follows:
#Slf4j
#Component("AccMemberDetailsApiControllerImpl")
public class AccMemberDetailsApiControllerImpl implements MemberDetailsApiController {
private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type";
private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
private static final String USERID_PARAMETER_NAME = "userId";
private static final String VEHICLEID_PARAMETER_NAME = "vehicleId";
private static final ObjectMapper mapper = new ObjectMapper();
/**
* This constant is used to check whether or not the response from ACC is an empty JSON string
*/
private static final String EMPTY_RESPONSE = "{}";
#Value("${com.blss.memberServices.provider.posServiceURL}")
private String accPosServiceURL;
#Autowired
private RestTemplate restTemplate;
#Autowired
private AccTokenUtility accTokenUtility;
#Autowired
private ResourceMessage resourceMessage;
void setAccTokenUtility(AccTokenUtility accTokenUtility) {
this.accTokenUtility = accTokenUtility;
}
void setResourceMessage(ResourceMessage resourceMessage) {
this.resourceMessage = resourceMessage;
}
/**
* #see MemberDetailsApiController#getMemberDetails(String, String)
*/
#Override
public MemberDetailsModel getMemberDetails(String storeId, String membershipIdentifier) {
/**
* Getting CAD token
*/
String token = accTokenUtility.getCadToken();
/**
* Preparing the request
*/
HttpHeaders headers = new HttpHeaders();
// headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.set(CONTENT_TYPE_HEADER_NAME, MediaType.APPLICATION_JSON_VALUE);
headers.set(AUTHORIZATION_HEADER_NAME, token);
HttpEntity<String> entity = new HttpEntity<>(headers);
/**
* Creating the dispatch URL by means of userId and vehicleId
*/
String dispatchURL = accPosServiceURL + "DispatchedEvent/{userId}/{vehicleId}";
/**
* Creating the URL variables and being valued by corresponding method parameters
*/
Map<String, String> parameters = new HashMap<>();
// parameters.put(USERID_PARAMETER_NAME, storeId);
parameters.put(USERID_PARAMETER_NAME, "mr2");
// parameters.put(VEHICLEID_PARAMETER_NAME, membershipIdentifier);
parameters.put(VEHICLEID_PARAMETER_NAME, "VEH1");
/**
* Calling the rest webservice and returning response with body of type {#link AccMemberDetails}
*/
ResponseEntity<String> response;
MemberDetailsModel memberDetailsModel = null;
AccMemberDetails accMemberDetails;
try {
response = restTemplate.exchange(dispatchURL, HttpMethod.GET, entity, String.class, parameters);
if (response == null || StringUtils.isBlank(response.getBody()) || EMPTY_RESPONSE.equals(response.getBody())) {
throw new ResourceNotFoundException(resourceMessage.getMessage(MEMBER_ERROR_NOT_FOUND, storeId, membershipIdentifier));
} else {
accMemberDetails = deserialize(response.getBody(), AccMemberDetails.class);
String accErrorMessage = accMemberDetails.getUserMessage();
if (!StringUtils.isBlank(accErrorMessage)) {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_ERROR_MESSAGE_FROM_API, "ACC", accErrorMessage));
}
memberDetailsModel = convert(accMemberDetails);
}
} catch (RestClientException e) {
handleExceptions(e, storeId, membershipIdentifier);
}
return memberDetailsModel;
}
/**
* This method is responsible for deserializing string REST response into an object of type {#link AccMemberDetails}
*/
<T> T deserialize(final String response, final Class<T> responseClass) {
try {
return mapper.readValue(response, responseClass);
} catch (IOException e) {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_ERROR_MAP_RESPONSE_OBJECT), e);
}
}
/**
* This method is responsible for converting an instance of type {#link AccMemberDetails} to an instance of type
* {#link MemberDetailsModel}
*
* #param accMemberDetails an instance of type {#link AccMemberDetails}
* #return an instance of type {#link MemberDetailsModel}
*/
MemberDetailsModel convert(AccMemberDetails accMemberDetails) {
MemberDetailsModel memberDetailsModel = new MemberDetailsModel();
memberDetailsModel.setEventId(accMemberDetails.getEventId());
memberDetailsModel.setMemberName(accMemberDetails.getMemberName());
memberDetailsModel.setMembershipNumber(accMemberDetails.getMembershipNumber());
memberDetailsModel.setMembershipLevel(accMemberDetails.getPricingLevel());
return memberDetailsModel;
}
/**
* This method is responsible for handling Exceptions may be thrown by ACC REST webservice
*
* #param e an instance of type {#link RestClientException}
* #param storeId an instance of type {#link String} and used in building exception messages
* #param membershipIdentifier an instance of type {#link String} and used in building exception messages
*/
private void handleExceptions(RestClientException e, String storeId, String membershipIdentifier) {
if (e instanceof HttpStatusCodeException) {
HttpStatusCodeException httpStatusCodeException = (HttpStatusCodeException) e;
HttpStatus httpStatusCode = httpStatusCodeException.getStatusCode();
if (404 == httpStatusCode.value()) {
throw new ResourceNotFoundException(resourceMessage.getMessage(MEMBER_ERROR_NOT_FOUND, storeId, membershipIdentifier), e);
} else if (500 == httpStatusCode.value()) {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_SERVER_ERROR, "ACC"), e);
} else {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_HTTP_STATUS_CODE_ERROR, "HttpStatusCodeException", "ACC"), e);
}
} else {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_REST_CLIENT_ERROR, "RestClientException", "ACC"), e);
}
}
Problem
However I got UnhandledHttpStatusException after calling "restTemplate.exchange(dispatchURL, HttpMethod.GET, entity, String.class, parameters);" in the code snippet. the exception stack trace is as follows:
Caused by: org.springframework.web.client.UnknownHttpStatusCodeException: Unknown status code [443] null
at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:60)
at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:50)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:629)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:565)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:484)
at com.blss.retailServices.memberServices.controllers.impl.acc.AccMemberDetailsApiControllerImpl.getMemberDetails(AccMemberDetailsApiControllerImpl.java:110)
Now I would be grateful if anyone could suggest me a solution.
I called this webservice with curl by using "-v" in order to get more info in response. As a result, I got the same exception (443) from their side. So, It sounds like they should have a better exception handler to return meaningful exception messages.

inputstream null pointer exception when using modified last.fm's Caller.java

For some reason I'm getting null pointer exception. It's downloading the image here and logcat points me to call
public Result call(final String method, final String apiKey, final String... params) {
return call(method, apiKey, map(params));
}
/**
* Performs the web-service call. If the <code>session</code> parameter is
* <code>non-null</code> then an authenticated call is made. If it's
* <code>null</code> then an unauthenticated call is made.<br/>
* The <code>apiKey</code> parameter is always required, even when a valid
* session is passed to this method.
*
* #param method The method to call
* #param apiKey A Last.fm API key
* #param params Parameters
* #param session A Session instance or <code>null</code>
* #return the result of the operation
*/
public Result call(final String method, final String apiKey, Map<String, String> params) {
params = new WeakHashMap<String, String>(params);
InputStream inputStream = null;
// no entry in cache, load from web
if (inputStream == null) {
// fill parameter map with apiKey and session info
params.put(PARAM_API_KEY, apiKey);
try {
final HttpURLConnection urlConnection = openPostConnection(method, params);
inputStream = getInputStreamFromConnection(urlConnection);
if (inputStream == null) {
lastResult = Result.createHttpErrorResult(urlConnection.getResponseCode(),
urlConnection.getResponseMessage());
return lastResult;
}
} catch (final IOException ignored) {
}
}
try {
final Result result = createResultFromInputStream(inputStream);
lastResult = result;
return result;
} catch (final IOException ignored) {
} catch (final SAXException ignored) {
}
return null;
}
It finally cracks at the line "new InputSource(new InputStreamReader(inputStream, "UTF-8")));".
/**
* #param inputStream
* #return
* #throws SAXException
* #throws IOException
*/
private Result createResultFromInputStream(final InputStream inputStream) throws SAXException,
IOException {
final Document document = newDocumentBuilder().parse(
new InputSource(new InputStreamReader(inputStream, "UTF-8")));
final Element root = document.getDocumentElement(); // lfm element
final String statusString = root.getAttribute("status");
final Status status = "ok".equals(statusString) ? Status.OK : Status.FAILED;
if (status == Status.FAILED) {
final Element errorElement = (Element)root.getElementsByTagName("error").item(0);
final int errorCode = Integer.parseInt(errorElement.getAttribute("code"));
final String message = errorElement.getTextContent();
return Result.createRestErrorResult(errorCode, message);
} else {
return Result.createOkResult(document);
}
}
Any ideas? I have no idea what might be wrong. If sufficient info is provided then let me know - I'll get what you need. I'm a beginner. :)

Categories

Resources