2014-06-04 5 views
0

Je développe un module Zend Framework 2 qui représente un service Web RESTful. Le contrôleur prend deux paramètres en entrée (à partir d'une application externe), interroge la base de données spécifiée avec ces paramètres et renvoie un JSON.Service Web RESTful avec Zend Framework 2

AlbumController.php

<?php 
namespace Album\Controller; 


use Album\Model\Album; 
use Album\Model\AlbumTable; 
use Zend\Mvc\Controller\AbstractRestfulController; 
use Zend\Http\Request; 
use Zend\View\Model\JsonModel; 
use Zend\Mvc\Controller\Plugin; 

class AlbumController extends AbstractRestfulController 
{ 

    /*public function indexAction() 
    { 
     return array(); 
    }*/ 

    protected $albumTable; 

    public function getList() 
    { 

     $request = $this->getRequest(); 

     // if I set par1 and par statically, the service works 
     $par1 = $request->getPost('par1'); 
     $par2 = $request->getPost('par2'); 

     $results = $this->getAlbumTable()->getAlbumByYearAndGenre($par1, $par2); 
     $data = array(); 

     foreach ($results as $result) { 
      $data[] = $result; 
     } 

     return new JsonModel(array(
      'Albums' => $data 
     )); 
    } 

    public function getAlbumTable() 
    { 
     if (! $this->albumTable) { 
      $sm = $this->getServiceLocator(); 
      $this->albumTable = $sm->get('Album\Model\AlbumTable'); 
     } 
     return $this->albumTable; 
    } 

    public function get($id) 
    { 
     // TODO: Implement Method 
    } 

    public function create($data) 
    { 
     // TODO: Implement Method 
    } 

    public function update($id, $data) 
    { 
     // TODO: Implement Method 
    } 

    public function delete($id) 
    { 
     // TODO: Implement Method 
    } 
} 

AlbumTable.php

<?php 
namespace Album\Model; 

use Zend\Db\TableGateway\TableGateway; 
use Zend\ServiceManager\ServiceLocatorAwareInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class AlbumTable implements ServiceLocatorAwareInterface 

{ 

protected $tableGateway; 
protected $serviceLocator; 
protected $adapter; 

public function __construct(TableGateway $tableGateway) 
{ 
    $this->tableGateway = $tableGateway; 
} 

public function fetchAll() 
{ 
    $resultSet = $this->tableGateway->select(); 
    return $resultSet; 
} 

public function setServiceLocator(ServiceLocatorInterface $serviceLocator) { 
    $this->serviceLocator = $serviceLocator; 
} 

public function getServiceLocator() { 
    return $this->serviceLocator; 
} 

public function getAdapter() 
{ 
    if (!$this->adapter) { 
     $sl = $this->getServiceLocator(); 
     $this->adapter = $sl->get('db2'); 
    } 
    return $this->adapter; 
} 

public function getAlbumByYearAndGenre($par1, $par2) 
{ 




    $sql = "my query"; 

    $statement = $this->getAdapter()->query($sql); 
    return $statement->execute(); 
} 

}

L'application externe (une application Android) utilise un JSONParser pour récupérer quelques informations:

public class JSONParser { 

    static InputStream is = null; 
    static JSONObject jObj = null; 
    static String json = ""; 


    public JSONParser() { 

    } 


    public JSONObject makeHttpRequest(String url, String method, 
      List<NameValuePair> params) { 


     try { 


      if(method == "POST"){ 

       DefaultHttpClient httpClient = new DefaultHttpClient(); 
       HttpPost httpPost = new HttpPost(url); 
       httpPost.setEntity(new UrlEncodedFormEntity(params)); 

       HttpResponse httpResponse = httpClient.execute(httpPost); 
       HttpEntity httpEntity = httpResponse.getEntity(); 
       is = httpEntity.getContent(); 
       httpClient.close(); 
      }else if(method == "GET"){ 

       DefaultHttpClient httpClient = new DefaultHttpClient(); 
       String paramString = URLEncodedUtils.format(params, "utf-8"); 
       url += "?" + paramString; 
       HttpGet httpGet = new HttpGet(url); 

       HttpResponse httpResponse = httpClient.execute(httpGet); 
       HttpEntity httpEntity = httpResponse.getEntity(); 
       is = httpEntity.getContent(); 
       httpClient.close(); 
      }   

     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        is, "iso-8859-1")); 
      StringBuilder sb = new StringBuilder(); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
      is.close(); 
      json = sb.toString(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


     try { 
      jObj = new JSONObject(json); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return jObj; 

    } 
} 

Pour simuler le comportement de l'application que je créé un JSONParserTest:

public class JSONParserTest { 
    public static void main(String[] args) { 
     JSONParser jparser = new JSONParser(); 
     String url = "myurl"; 
     int par1 = 0; 
     String par2 = "..." 
     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     params.add(new BasicNameValuePair("par1", Integer.toString(par1))); 
     params.add(new BasicNameValuePair("par2", par2); 
     JSONObject json = jparser.makeHttpRequest(url, "POST", params); 
     try { 
      JSONArray jarray = json.getJSONArray("Albums"); 
      System.out.println(jarray.toString()); 
      System.out.println(json.toString()); 
      for(int i = 0; i < jarray.length(); i++) 
      { 
       JSONObject object = jarray.getJSONObject(i); 
       System.out.println(object.getString("par1")); 
       System.out.println(object.getString("par2")); 
      } 

     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 

problème est si je mets les paramètres statiquement dans le contrôleur et j'ouvre le chemin, je reçois le JSON. Mais si je lie les paramètres à la requête, il semble que zend ne les obtienne pas (et j'obtiens un JSON vide). En fait, c'est l'exception:

org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1] 
    at org.json.JSONTokener.syntaxError(JSONTokener.java:433) 
    at org.json.JSONObject.<init>(JSONObject.java:188) 
    at org.json.JSONObject.<init>(JSONObject.java:314) 
    at com.example.mypackage.jclasses.JSONParser.makeHttpRequest(JSONParser.java:89) 
    at com.example.mypackage.jclasses.JSONParserTest.main(JSONParserTest.java:22) 
Exception in thread "main" java.lang.NullPointerException 
    at com.example.mypackage.jclasses.JSONParserTest.main(JSONParserTest.java:24) 

(ligne 22 est JSONObject json = jparser.makeHttpRequest(url, "POST", params); et la ligne 24 est: JSONArray jarray = json.getJSONArray("Albums");)

Répondre

0

Il semble que la chaîne JSON est malformé. Essayez de faire un System.out.println (sb.toString()); dans votre classe JSONParser pour voir comment StringBuilder construit de Json.

try { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(
    is, "iso-8859-1")); 
    StringBuilder sb = new StringBuilder(); 
    String line = null; 
    while ((line = reader.readLine()) != null) { 
    sb.append(line + "\n"); 
    } 
    is.close(); 
    System.out.println(sb.toString()); 
    json = sb.toString(); 
} catch (Exception e) { 
    e.printStackTrace(); 
}