通过Retrofit在安卓上使用Rest web服务登录不起作用

14

我正在使用Retrofit 2制作一个Android应用程序。我的REST Api都是使用Liferay编写的。现在在Liferay中,我所看到的是,要访问Web服务,我们需要先进行身份验证。所以我已经像这样进行了身份验证:

http://test:q1w2e3r4@192.168.0.110:8080/liferay-portlet/api/secure/jsonws/

Liferay有自己的用户认证方法,我们已经进行了重写。我用Postman检查了Web服务调用,它正常工作。

URL:http://test:q1w2e3r4@192.168.0.110:8080/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name

表单编码值
companyId:10154
screenName:xyz
password:xyz
active:true

如果我在Postman中放置这个请求,它会正确地获取JSON响应。

现在当我从我的Android代码中调用相同的请求时,我会得到一个“未经授权”的响应。

我的Retrofit服务

public interface LoginApi {    
    @FormUrlEncoded
    @POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
    Call<User> login(@Field("companyId")long companyId,@Field("screenName")String screenName,@Field("password")String password,@Field("active")boolean active);
}

我的RestApiManager类(此类用于调用服务接口并创建Retrofit Builder)

public class RestApiManager {

    private LoginApi loginApi;

    public LoginApi login() {
        if (loginApi==null) {
            GsonBuilder gson=new GsonBuilder();
            gson.registerTypeAdapter(String.class, new StringDeserializer());
            Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("http://test:q1w2e3r4@192.168.0.110:8080")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
            loginApi=retrofit.create(LoginApi.class);
    }
    return loginApi;
}

调用RestApiManager

Call<User> callUser=restApiManager.login().login(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
callUser.enqueue(new Callback<User>() {
    @Override
    public void onResponse(Response<User> response, Retrofit retrofit) {
        Log.d("Login","Login Response:"+response.body());
    }

    @Override
    public void onFailure(Throwable t) {
        Log.d("Login","Login Response:"+t.getMessage());
    }
});

1
什么是响应?调用了哪个回调函数? - Blackbelt
你应该添加日志记录。 - Rodrigo Henriques
5个回答

5
看起来您的请求可能应该有一个JSON body而不是POST变量? 您正在调用一个JSON webservice,您的示例参数更像JSON而不是POST。如果是这样的话,您可以将参数封装在一个对象中 -
public class User {
    int companyId;
    String screenName;
    String password;
    boolean active;

    User(int companyId, String screenName, String password, boolean active) {
        this.companyId = companyId;
        this.screenName = screenName;
        this.password = password;
        this.active = active;
}

你的界面将是--

public interface LoginApi {    
    @POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
    Call<User> login(@Body User user);
}

并构建您的调用方式为--
User user = new User(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
Call<User> callUser = restApiManager.login().login(user);

1
我尝试在我的本地电脑上运行你的演示代码,但由于你的服务器在本地网络中,所以没有成功。关于这个问题,如果你在服务器端使用cookie或session进行授权,我建议你按照以下方式设置setCookieHandler,你可以在这里找到PersistentCookieStore.java。
private PersistentCookieStore cookieStore= new PersistentCookieStore(JApplication.getInstance().getApplicationContext());
CookieManager cookieManager = (new CookieManager(
            cookieStore,
            CookiePolicy.ACCEPT_ALL));

okHttpClient.setCookieHandler(cookieManager);
OkClient okClient = new OkClient(okHttpClient);
RestAdapter restAdapter = new RestAdapter.Builder()
            .setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade request) {
                    request.addHeader(Constant.Header_UserAgent, getUserAgent());
                }
            })
            .setClient(okClient)
            .setEndpoint(URL)
            .setErrorHandler(new HttpErrorHandler())
            .setConverter(new GsonConverter(gson))
            .build();

1

如果不知道您的 Retrofit Api 正在构建哪个请求,那么对我们来说帮助您可能会比较困难。

所以我建议您配置一个 Logging Interceptor,以便了解实际发生的情况,然后如果您仍然不知道发生了什么,可以向我们提供更多信息。

请查看此答案以了解如何使用 Retrofit 2 配置 LoggingInterceptor: Logging with Retrofit 2

希望这可以帮助到您。

最好的问候。


1
跨平台的会话管理与在浏览器上的工作方式不同。Postman是一个在浏览器平台上工作的Web客户端。
1. 一种解决方法是在设备上维护cookie。
请查看此答案 使用Android应用程序管理会话
2. 另一种解决方法是使用基于Json Web Token的身份验证。

0

我尝试了这里提供的所有解决方案,但不幸的是都没有起作用。我发现唯一的解决方法是使用Liferay移动SDK从Android中调用Liferay服务。它已经有了调用Liferay服务的方法和服务。您还可以调用自定义服务。更多信息请参见Liferay Mobile SDK


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接