2015-08-24 11 views
6

Attualmente sto usando il seguente codice di inizializzazione sul mio modulo apiPerché il controller del riposo Yii2 fornisce una risposta in formato XML?

public function init() 
{ 
    parent::init(); 
    Yii::$app->response->format = Response::FORMAT_JSON; 
} 

mio API restituisce la risposta in formato XML nel seguente esempio.

public function actionTest() 
{ 
    $items = ['one', 'two', 'three' => ['a', 'b', 'c']]; 
    return $items; 
} 

Questa è la risposta:

<response> 
    <item>one</item> 
    <item>two</item> 
    <three> 
    <item>a</item> 
    <item>b</item> 
    <item>c</item> 
    </three> 
</response> 

L'unico modo in cui posso farlo funzionare è con l'aggiunta di questa linea a ciascuno dei comportamenti del controller. Ho letto la documentazione che dice che posso inizializzare questo sulla classe del modulo, quindi non ho bisogno di farlo in ogni controller. Non so perché dia l'XML comunque. Anche nel caso nel caso in cui l'unico modo è di aggiungerlo ai miei comportamenti, devo scrivere codice per gestire nome, codice, stato, tipo, precedente e codice o Yii fornisce yii \ rest \ Controller e yii \ rest \ ActiveController che gestisce automaticamente questo. Chiaramente vengono emessi automaticamente quando si verifica un errore.

{"name":"Not Found" 
"message":"Page not found.", 
"code":0, 
"status":404 
"type":"yii\\web\\NotFoundHttpException" 
"previous":{"name":"Invalid Route","message":"Unable to resolve the request: api/home/", 
"code":0,"type":"yii\\base\\InvalidRouteException" 
} 
} 
+0

Può essere che qualcos'altro come un'azione di comportamento o di classe cambia il formato di risposta app? Puoi provare var-dumping 'Yii :: $ app-> response-> format' in qualsiasi azione appena prima di restituire un valore. – Beowulfenator

+0

Ottengo questo errore di analisi XML: non ben formato Numero riga 1, colonna 7: stringa (3) "xml" ------^ –

risposta

4

In Yii2 il tipo di risposta predefinito delle applicazioni è XML (e suppongo che sia anche predefinito per REST). Durante la connessione HTTP, entrambe le parti dichiarano quale tipo di dati è in grado di inviare e/o ricevere. Se questa informazione non viene trasmessa al server, il tipo di dati predefinito viene inviato (anche se hai specificato che dovrebbe essere JSON nella tua app) per garantire una comunicazione corretta. Se si desidera ricevere dati JSON, è necessario aggiungere l'intestazione Accept: application/json alla richiesta. E probabilmente non devi specificarlo in codice php perché Yii2 dovrebbe dedurlo dalle intestazioni delle richieste.

È possibile trovare ulteriori spiegazioni come funziona here.

3

I test del codice e 'un lavoro perfettamente

mio regolatore questo:

<?php 

namespace backend\controllers; 


use yii\rest\Controller; 
use yii; 
use yii\web\Response; 

class TestController extends Controller{ 

    public function init() 
    { 
     parent::init(); 
     Yii::$app->response->format = Response::FORMAT_JSON; 
    } 

    public function actionTest(){ 
     $items = ['one', 'two', 'three' => ['a', 'b', 'c']]; 
     return $items; 
    } 
} 

uscita:

{"0":"one","1":"two","three":["a","b","c"]} 

controllare lo spazio dei nomi o inviare il proprio codice!

+0

'init()' appartiene alla mia classe Module non controller. In realtà questo mi dà ancora una risposta XML. –

+2

Ho la stessa configurazione ma fornisce l'output XML sempre sul browser e l'output JSON in POSTMAN. – ankitr

+2

E 'possibile che sia causato dalle intestazioni del browser. Probabilmente Yii non invierà JSON se il browser non aggiunge l'intestazione 'Accept: application/json'. – Glapa

4

Dopo tre giorni dolorosi, ho trovato le soluzioni. A volte è abbastanza difficile spiegare questo problema quando si proviene da un intero mondo JSON di ExpressJS e NodeJS. Logicamente, ciò che fa Yii2 è perfetto, d'altra parte le API RESTful al 90% si aspettano che l'output sia in JSON, quindi non si desidera esplicitamente impostare le intestazioni delle richieste ogni volta che si effettua una chiamata API.

I browser per impostazione predefinita aggiungono intestazioni di richiesta come "Applicazione/XML", quindi ciò che viene visualizzato sullo schermo è XML anziché JSON.

Il negoziatore del contenuto di Yii2 al momento del ricevimento delle intestazioni in quanto application/xml formatta l'output in XML. Se fai una stessa richiesta usando CURL o PostMan con intestazioni come "Applicazione/JSON" otterrai l'output desiderato.

Se si desidera ignorare questo comportamento poi basta aggiungere la funzione di seguito nel controller e sono i seguenti: -

uso Yii \ web \ Response; usa yii \ helpers \ ArrayHelper;

public function behaviors() 
 
    { 
 
     return ArrayHelper::merge(parent::behaviors(), [ 
 
      [ 
 
       'class' => 'yii\filters\ContentNegotiator', 
 
       'only' => ['view', 'index'], // in a controller 
 
       // if in a module, use the following IDs for user actions 
 
       // 'only' => ['user/view', 'user/index'] 
 
       'formats' => [ 
 
        'application/json' => Response::FORMAT_JSON, 
 
       ], 
 
       'languages' => [ 
 
        'en', 
 
        'de', 
 
       ], 
 
      ], 
 
     ]); 
 
    }

Problemi correlati