我正在使用 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
如果我把它放在邮递员中,它会正确地获取json响应。
现在,当我从我的Android代码中调用相同内容时,我得到了回复"未经授权"。
我的改造服务
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);
}
My RestApiManager Class(此类用于调用服务接口并创建改造构建器)
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());
}
});
答案 0 :(得分:5)
看起来您的请求可能应该有一个JSON正文而不是POST变量?您正在调用JSON Web服务,并且您的示例参数看起来比POST更多JSON。如果是这样,那么您可以将参数封装在对象中 -
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 :(得分:1)
跨平台的会话管理不像浏览器那样工作。 Postman是一个在浏览器平台上运行的Web客户端。
1.一种解决方案是在设备上维护cookie。
检查此答案manage sessions with Android Application。
2.另一种解决方案是使用基于Json Web Token的身份验证。
答案 2 :(得分:1)
我试图在我的本地PC上运行您的演示代码,但是没有幸运,因为您的服务器在您的局域网中,关于这个问题,如果您在服务器端使用cookie或会话授权,我建议您尝试setCookieHandler如下,你可以找到PersistentCookieStore.java here
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();
答案 3 :(得分:1)
如果不确切知道您的Retrofit Api正在构建哪个请求,我们可能很难帮助您。
因此,我建议您配置一个记录拦截器,以便与实际发生的事情保持联系,如果您仍然不知道发生了什么,您可以通过更多信息回复我们。
检查此答案以了解如何使用Retrofit 2配置LoggingInterceptor: Logging with Retrofit 2
希望它有所帮助。
祝你好运。
答案 4 :(得分:0)
我尝试了这里给出的所有解决方案,但遗憾的是没有任何工作。我发现从android内部调用lifer服务的唯一解决方案是使用lifer mobile sdk。它已经有方法和服务来调用liferay服务。您也可以调用您的自定义服务。更多信息 Liferay Mobile SDK