Volley JsonObjectRequest Post 요청이 작동하지 않습니다.


78

요청을 위해 Android Volley를 사용하고 있습니다. 그래서이 코드를 사용합니다. 나는 한 가지를 이해하지 못합니다. 내 서버에서 params가 항상 null인지 확인합니다. getParams ()가 작동하지 않는다고 생각합니다. 이 문제를 해결하려면 어떻게해야합니까?

 RequestQueue queue = MyVolley.getRequestQueue();
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        System.out.println(response);
                        hideProgressDialog();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                      hideProgressDialog();
                    }
                }) {
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("id","1");
                params.put("name", "myname");
                return params;
            };
        };
        queue.add(jsObjRequest);

5
질문에 대한 Thx. JsonObjectRequest에도 문제가 있습니다. 그래서 저는 정상적인 StringRequest를 사용합니다. 발리 버그처럼 보입니다. 어떻게 해결했는지 알 수 있을까요?
Thein dec

물론입니다. 여기 에서처럼 CustomJsonObjectRequest를 만들어야합니다. stackoverflow.com/questions/19837820/…
pmb

물어봐 주셔서 감사합니다! 난 .. 너무 같은 문제가
발라 비슈누에게

1
생성자의 세 번째 매개 변수가 null이기 때문입니다.
njzk2 2014-06-04

@ njzk2 : pmb가 JSON 본문이 아닌 URL 인코딩 매개 변수를 사용하여 POST 요청을 보내려고한다고 생각합니다. LOG_TAG의 대답은 가장 잘 보입니다. 매개 변수를 받아들이고 여전히 JSON 응답을 허용하는 사용자 지정 클래스입니다.
twelve17 2014-08-11

답변:


134

이 도우미 클래스를 사용해보십시오

import java.io.UnsupportedEncodingException;
import java.util.Map;    
import org.json.JSONException;
import org.json.JSONObject;    
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;

public class CustomRequest extends Request<JSONObject> {

    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomRequest(String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }
}

활동 / 조각에서 이것을 사용하십시오

RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
CustomRequest jsObjRequest = new CustomRequest(Method.POST, url, params, this.createRequestSuccessListener(), this.createRequestErrorListener());

requestQueue.add(jsObjRequest);

1
Thx 작동합니다! JsonObjectRequest에서 getParams () 재정의가 작동하지 않는 이유는 무엇입니까? 발리 버그인가요?
Thein dec

1
이것은 버그가 아니며 JsonObjectRequest 가 getBody ()를 직접 호출하는 JsonRequest를 생성자 두 번째 매개 변수 (requestBody 호출)를 contentType으로 인코딩 하기 위해 확장했기 때문에 getParams ()가 호출되지 않으므로 getParam () 메서드를 무시합니다.
VinceStyling

1
@LOG_TAG is this.createRequestSuccessListener (), this.createRequestErrorListener ()); 이해가 안 돼요 설명 해주세요.
ik024 2014 년

2
@Droider 적절한 응답 처리 개체를 만드는 메서드입니다. 가독성을 위해 개별 메서드로 만들어 졌을 가능성이 높습니다. new키워드를 사용하여 제자리에 객체를 생성 할 수도 있지만 해당 객체의 코드 크기에 따라 한눈에 읽기 어려울 수 있습니다.
jnfjnjtj

2
나는 문제의 많은 데,이 작업 좋은되었다 : D 덕분에
하비에르

30

사용자 지정을 만들고 메서드를 JSONObjectReuqest재정의 getParams하거나 JSONObject요청 본문에 넣을 수 있도록 생성자에 제공 할 수 있습니다 .

이렇게 (코드를 편집했습니다) :

JSONObject obj = new JSONObject();
obj.put("id", "1");
obj.put("name", "myname");

RequestQueue queue = MyVolley.getRequestQueue();
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,obj,
    new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
             System.out.println(response);
             hideProgressDialog();
        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
             hideProgressDialog();
        }
    });
queue.add(jsObjRequest);

좋고 빠르다! 하지만 x-www-urlencoded가 필요한 경우 발리에서 수행합니까?
Poutrathor

잘 모르겠지만 쉽게 테스트 할 수 있습니다.
Itai Hanski 2013

getParams가 호출되지 않는 것이 확실합니까? 반대로 코드는 getBody () 및 getPostParams ()에 의해 호출된다는 것을 보여 주며 여기에 반대로 자신을 말합니다. stackoverflow.com/questions/18484647/…
Poutrathor

당신 말이 맞아요, 나는 방법 사이에 섞여 있습니다 (충분하지 않은 수면). 내 대답을 편집했습니다.
Itai Hanski 2013

POST 및 GET 방법으로 시도했습니다. 둘 다 작동하지 않습니다. 나는 생각이 없다.
Amir Fazwan

5

나를 위해 쉬운 것! 몇 주 전에 얻었습니다.

이것은 포스트 요청이 getBody()아닌 방법으로 진행됩니다 getParams().

여기 내 것입니다.

    @Override
/**
 * Returns the raw POST or PUT body to be sent.
 *
 * @throws AuthFailureError in the event of auth failure
 */
public byte[] getBody() throws AuthFailureError {
    //        Map<String, String> params = getParams();
    Map<String, String> params = new HashMap<String, String>();
    params.put("id","1");
    params.put("name", "myname");
    if (params != null && params.size() > 0) {
        return encodeParameters(params, getParamsEncoding());
    }
    return null;

}

(getParams에 작성한 매개 변수를 POST하고 싶다고 가정했습니다)

생성자 내부의 요청에 매개 변수를 제공했지만 요청을 즉석에서 생성하므로 getBody () 메서드의 재정의 내에서 매개 변수를 하드 코딩 할 수 있습니다.

내 코드는 다음과 같습니다.

    Bundle param = new Bundle();
    param.putString(HttpUtils.HTTP_CALL_TAG_KEY, tag);
    param.putString(HttpUtils.HTTP_CALL_PATH_KEY, url);
    param.putString(HttpUtils.HTTP_CALL_PARAM_KEY, params);

    switch (type) {
    case RequestType.POST:
        param.putInt(HttpUtils.HTTP_CALL_TYPE_KEY, RequestType.POST);
        SCMainActivity.mRequestQueue.add(new SCRequestPOST(Method.POST, url, this, tag, receiver, params));

더 많은 것을 원한다면이 마지막 문자열 매개 변수 는 다음과 같습니다.

param = JsonUtils.XWWWUrlEncoder.encode(new JSONObject(paramasJObj)).toString();

paramasJObj는 다음과 같습니다. {"id"="1","name"="myname"}일반적인 JSON 문자열입니다.


여기서 매개 변수를 전달하는 방법을 알지 못합니다. 문자열 s = new String (param). 뭐야?
pmb

내 매개 변수가있는 문자열 일뿐입니다. 생성자에 보냅니다. 좀 더 보여 드릴게요.
Poutrathor

getParams () 메서드에서 해당 매개 변수를 보내는 방법을 알려줄 수 있다면 @poutrathor에게 감사드립니다.
pmb

아. 따라서 매개 변수로 사용하려고합니다. 호기심으로 서버에 무엇을 게시합니까?
Poutrathor 2013

내 목표는 getParams에 쓴 것처럼 매개 변수를 보내야하는데 jsonObject를 보낼 수 없다는 것입니다.
pmb

3

JsonObject 요청으로 작업 할 때 초기화에서 링크를 전달한 직후 매개 변수를 전달해야합니다. 다음 코드를 살펴보십시오.

        HashMap<String, String> params = new HashMap<>();
        params.put("user", "something" );
        params.put("some_params", "something" );

    JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, "request_URL", new JSONObject(params), new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {

           // Some code 

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            //handle errors
        }
    });


}

1

요청 클래스에서 getParams 메서드를 재정의하기 만하면됩니다. 나는 같은 문제가 있었고 답을 찾아 보았지만 적절한 것을 찾지 못했습니다. 문제는 get 요청과 달리 서버에서 리디렉션되는 post 매개 변수가 삭제 될 수 있습니다. 예를 들어, 이것을 읽으십시오 . 따라서 요청이 웹 서버에 의해 리디렉션되는 위험을 감수하지 마십시오. http : // example / myapp을 대상으로하는 경우 서비스의 정확한 주소 ( http://example.com/myapp/index.php) 를 언급하십시오 .
Volley는 괜찮고 완벽하게 작동합니다. 문제는 다른 곳에서 발생합니다.


1

재정의 함수 getParams가 제대로 작동합니다. POST 메서드를 사용하고 jBody를 null로 설정했습니다. 그것이 작동하지 않는 이유입니다. null jBody를 보내려면 GET 메서드를 사용할 수 있습니다. getParams 메서드를 재정의했으며 POST 메서드 (및 jBody! = null)를 사용하여 GET 메서드 (및 null jBody)와 함께 작동합니다.

또한 여기에 모든 예가 있습니다.


1

한 번 같은 문제가 발생했습니다. 빈 POST 배열은 요청의 리디렉션으로 인해 발생합니다 (서버 측에서). URL을 수정하여 서버에 도달 할 때 리디렉션 될 필요가 없습니다. 예를 들어 서버 측 앱에서 .htaccess 파일을 사용하여 https를 강제 실행하는 경우 클라이언트 요청에 "https : //"접두사가 있는지 확인합니다. 일반적으로 리디렉션이 발생하면 POST 어레이가 손실됩니다. 이게 도움이 되길 바란다!


0

그것은 자바 코드에서 Volley Json 요청 및 응답을 호출하기 위해 이것을 시도 할 수 있습니다.

public void callLogin(String sMethodToCall, String sUserId, String sPass) {
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
                Request.Method.POST, ConstantValues.ROOT_URL_LOCAL + sMethodToCall.toString().trim(), addJsonParams(sUserId, sPass),
//                JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, object,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d("onResponse", response.toString());
                        Toast.makeText(VolleyMethods.this, response.toString(), Toast.LENGTH_LONG).show(); // Test

                        parseResponse(response);
//                        msgResponse.setText(response.toString());
//                        hideProgressDialog();
                    }
                },
                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        VolleyLog.d("onErrorResponse", "Error: " + error.getMessage());
                        Toast.makeText(VolleyMethods.this, error.toString(), Toast.LENGTH_LONG).show();
//                hideProgressDialog();
                    }
                }) {

            /**
             * Passing some request headers
             */
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> headers = new HashMap<String, String>();
                headers.put("Content-Type", "application/json; charset=utf-8");
                return headers;
            }


        };

        requestQueue.add(jsonObjectRequest);
    }

    public JSONObject addJsonParams(String sUserId, String sPass) {
        JSONObject jsonobject = new JSONObject();
        try {
//            {"id":,"login":"secretary","password":"password"}

            ///***//
            Log.d("addJsonParams", "addJsonParams");

//            JSONObject jsonobject = new JSONObject();

//            JSONObject jsonobject_one = new JSONObject();
//
//            jsonobject_one.put("type", "event_and_offer");
//            jsonobject_one.put("devicetype", "I");
//
//            JSONObject jsonobject_TWO = new JSONObject();
//            jsonobject_TWO.put("value", "event");
//            JSONObject jsonobject = new JSONObject();
//
//            jsonobject.put("requestinfo", jsonobject_TWO);
//            jsonobject.put("request", jsonobject_one);

            jsonobject.put("id", "");
            jsonobject.put("login", sUserId); // sUserId
            jsonobject.put("password", sPass); // sPass


//            js.put("data", jsonobject.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jsonobject;
    }

    public void parseResponse(JSONObject response) {

        Boolean bIsSuccess = false; // Write according to your logic this is demo.
        try {
            JSONObject jObject = new JSONObject(String.valueOf(response));
            bIsSuccess = jObject.getBoolean("success");


        } catch (JSONException e) {
            e.printStackTrace();
            Toast.makeText(VolleyMethods.this, "" + e.toString(), Toast.LENGTH_LONG).show(); // Test
        }

    }

0



gradle (앱) 빌드

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.1.0'
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.android.volley:volley:1.1.1'
}

안드로이드 매니페스트
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

MainActivity
JsonObjectRequest를 사용할 때 jsonobject를 보내고 jsonobject를 수신하는 것은 필수입니다. 그렇지 않으면 jsonobject 만 허용하므로 오류가 발생합니다.
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley

fun peticion(){
    val jsonObject = JSONObject()
    jsonObject.put("user", "jairo")
    jsonObject.put("password", "1234")
    val queue = Volley.newRequestQueue(this)
    val url = "http://192.168.0.3/get_user.php"
    // GET: JsonObjectRequest( url, null,
    // POST: JsonObjectRequest( url, jsonObject,
    val jsonObjectRequest = JsonObjectRequest( url, jsonObject,
        Response.Listener { response ->
            // Check if the object 'msm' does not exist
            if(response.isNull("msm")){
                println("Name: "+response.getString("nombre1"))
            }
            else{
                // If the object 'msm' exists we print it
                println("msm: "+response.getString("msm"))
            }
        },
        Response.ErrorListener { error ->
            error.printStackTrace()
            println(error.toString())
        }
    )
    queue.add(jsonObjectRequest)
}

파일 php get_user.php
<?php
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: *");
    // we receive the parameters
    $json = file_get_contents('php://input');
    $params = json_decode($json);
    error_reporting(0);
    require_once 'conexion.php';

    $mysqli=getConex();
    $user=$params->user;
    $password=$params->password;
    $res=array();
    $verifica_usuario=mysqli_query($mysqli,"SELECT * FROM usuarios WHERE usuario='$user' and clave='$password'");
    if(mysqli_num_rows($verifica_usuario)>0){
        $query="SELECT * FROM usuarios WHERE usuario='$user'";
        $result=$mysqli->query($query);
        while($row = $result->fetch_array(MYSQLI_ASSOC)){
            $res=$row;
        }
    }
    else{
        $res=array('msm'=>"Incorrect user or password");
    }
    $jsonstring = json_encode($res);
    header('Content-Type: application/json');
    echo $jsonstring;
?>

파일 PHP 연결
<?php
    function getConex(){
        $servidor="localhost";
        $usuario="root";
        $pass="";  
        $base="db";
        
        $mysqli = mysqli_connect($servidor,$usuario,$pass,$base);
        if (mysqli_connect_errno($mysqli)){
            echo "Fallo al conectar a MySQL: " . mysqli_connect_error();
        }
        $mysqli->set_charset('utf8');
        return $mysqli;
    }
?>

이 코드를 설명해 주시겠습니까? 지금은 이것이 어떻게 문제를 해결하는지 조금 불분명합니다.
라이언 M
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.