android 改造 2 post 到 laravel 不工作

android retrofit 2 post to laravel not working

我正在使用改造 2,试图将数据发送到我的 laravel 网络。

InitRetrofit.java

public class InitRetrofit {
    public static String API_URL = "http://192.168.1.2/sra-copy/public/";
    public static Retrofit setInit(){
        return new Retrofit.Builder().baseUrl(API_URL).addConverterFactory(GsonConverterFactory.create()).build();
    }

    public static ApiService getInstance(){
        return setInit().create(ApiService.class);
    }
}

ApiService.java

public interface ApiService {
    @FormUrlEncoded
    @POST("lapor/android")
    Call<ResponseLapor> input(@Field("lat") String lat,
                              @Field("lng") String lng,
                              @Field("jenis") String jns,
                              @Field("keterangan") String ket);
}

回应classResponseLapor.java

public class ResponseLapor {
    @SerializedName("message")
    @Expose
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message){
        this.message = message;
    }
}

调用改造

public void lapor(){
    lat = etLat.getText().toString();
    lng = etLng.getText().toString();
    keterangan = etKet.getText().toString();
    jns = "Ringan";

    ApiService api = InitRetrofit.getInstance();

    retrofit2.Call<ResponseLapor> call = api.input(lat, lng, jns, keterangan);
    call.enqueue(new Callback<ResponseLapor>() {
        @Override
        public void onResponse(retrofit2.Call<ResponseLapor> call, Response<ResponseLapor> response) {
            String message = response.body().getMessage();
            Toast.makeText(Lapor.this, message, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onFailure(retrofit2.Call<ResponseLapor> call, Throwable t) {
            Toast.makeText(Lapor.this, "Jaringan Error! "+t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

路线

Route::post('lapor/android', 'AndroidController@Lapor')->name('android.lapor');

控制器

public function Lapor(Request $request){
    // dd($request->all());
    $msg = array();
    if($request->jenis == "Ringan"){
        $rs = RumahSakit::select(DB::raw('*, ( 6367 * acos( cos( radians('.$request->lat.') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('.$request->lng.') ) + sin( radians('.$request->lat.') ) * sin( radians( lat ) ) ) ) AS distance'))->having('distance', '<', 25)->orderBy('distance')->get();
        DB::table('status')->insert([
            'nama_sts' => $rs->first()->nama_rs,
            'keterangan' => $request->keterangan,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        $msg["message"] = $rs->first()->nama_rs;
    }
    else{
        $msg["message"] = "Error Jenis Laporan";
    }
    echo json_encode($msg);
}

控制器在尝试从网络插入时工作。 当我第一次发送数据时,它没有显示任何吐司,然后第二次我得到这个错误:

"java.lang.NullPointerException: Attempt to invoke virtual method java.lang.String com.example.sra.response.ResponseLapor.getMessage()' on a null object reference

我认为错误与 URL 有关,因为我有另一个使用相同结构的 android 项目并且它成功地将数据插入本地主机(不是 laravel)只是原生 PHP.

更新
我终于通过尝试 post 使用 Postman 弄明白了,它给出错误 419 页面已过期,因为它没有 csrf 令牌(因为我 post 直接将它编辑到控制器而没有查看我可以添加csrf to),
所以我在中间件文件夹的 VerifyCsrfToken.php 上添加了 url 的例外,所以它变成了这样

class VerifyCsrfToken extends Middleware
{
    /**
     * Indicates whether the XSRF-TOKEN cookie should be set on the response.
     *
     * @var bool
     */
    protected $addHttpCookie = true;

    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        //
        '/lapor/android'
    ];
}

也许还有另一种方法可以做到这一点,比如在控制器内部生成 csrf 令牌。
希望这会对某人有所帮助。