我一直在使用Codename One 模拟器进行开发和测试,一切正常。
然而,当我在真正的Android设备上测试它时,我得到405 Method Not Allowed错误。这发生在POST和GET请求上。
我怀疑导致问题的是@Consume和@Produces。我该如何解决这个问题?
以下是我的服务器端代码:
@GET
@Path("/all/{language}")
@Produces("application/json")
public final Response getAllCelebrities(@PathParam("language") String language) {
String celebritiesJSONString = CelebrityActions.getAllCelebritiesNamesJSONString(language);
return Response.ok(celebritiesJSONString).build();
}
@POST
@Path("/login")
@Consumes("application/x-www-form-urlencoded")
@Produces("text/plain")
public final Response login(
@FormParam("loginid") String loginid,
@FormParam("password") String password
) {
System.out.println("login 0 started");
Long fanID;
try {
fanID = AccountsActions.login(loginid, password);
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
}
if (fanID == null) {
return responseFanIDNotFoundError();
}
System.out.println("This is printed out!!!");
System.out.println("login 100 ended");
return Response.ok().build();
}
这是执行login()方法后的日志:
login 0 started
This is printed out!!!
login 100 ended
这意味着服务器端方法已准备好返回200响应。
是什么导致Android客户端显示405 Method Not Allow错误?
编辑:我在这里添加我的客户端代码: (请注意,这个处理来自服务器的cookie)
public class Login extends PostConnection {
private final String LoginEndpoint = "account/login";
private String loginIDString;
private String loginPasswordString;
// Tested and works on simulator!
public Login(String loginIDString, String loginPasswordString) {
super();
endpoint = LoginEndpoint;
this.loginIDString = loginIDString;
this.loginPasswordString = loginPasswordString;
}
@Override
protected void prepareParametersMap() {
parametersMap = new HashMap<>();
parametersMap.put("loginid", loginIDString);
parametersMap.put("password", loginPasswordString);
}
}
public abstract class PostConnection extends PostPutConnection {
public PostConnection() {
super();
}
public boolean connect() throws IOException {
connectionRequest.setHttpMethod("POST");
return super.connect();
}
}
public abstract class PostPutConnection extends Connection {
protected HashMap<String, String> parametersMap;
public PostPutConnection() {
super();
}
protected static final void setPostParameters(ConnectionRequest connectionRequest, HashMap<String, String> parametersMap) {
Set<String> paramateterKeys = parametersMap.keySet();
Iterator<String> parameterKeysIterator = paramateterKeys.iterator();
while (parameterKeysIterator.hasNext()) {
String key = parameterKeysIterator.next();
String value = parametersMap.get(key);
connectionRequest.addArgument(key, value);
}
}
protected abstract void prepareParametersMap();
public boolean connect() throws IOException {
prepareParametersMap();
setPost();
setPostParameters();
return super.connect();
}
private void setPostParameters() {
setPostParameters(connectionRequest, parametersMap);
}
private final void setPost() {
connectionRequest.setPost(true);
}
}
public abstract class Connection {
private final static String protocol = "http";
private final static String domain = "192.168.0.109:20000";
protected ConnectionRequest connectionRequest;
protected String endpoint;
public Connection() {
super();
init();
}
protected void init() {
connectionRequest = new ConnectionRequest();
connectionRequest.setCookiesEnabled(true);
ConnectionRequest.setUseNativeCookieStore(true);
}
public boolean connect() throws IOException {
connectionRequest.setUrl(protocol + "://" + domain + "/" + endpoint);
NetworkManager.getInstance().addToQueueAndWait(connectionRequest);
int responseCode = getResponseCode();
return responseCode == 200 ? true : false;
}
private int getResponseCode() {
int responseCode = connectionRequest.getResponseCode();
return responseCode;
}
}
以下另一种方法: (请注意,这个不处理Cookie)
public class GetAllCelebrities extends GetConnection {
private final String GetCelebritiesEndpoint = "celebrity/all";
public GetAllCelebrities(String language) {
super();
endpoint = GetCelebritiesEndpoint + "/" + language;
}
}
public abstract class GetConnection extends Connection {
private Map<String, Object> responseData;
public GetConnection() {
super();
}
public boolean connect() throws IOException {
connectionRequest.setHttpMethod("GET");
boolean connectResult = super.connect();
if (!connectResult) {
return false;
}
responseData = getResponseResult();
return true;
}
private Map<String, Object> getResponseResult() throws IOException {
byte[] responseData = connectionRequest.getResponseData();
ByteArrayInputStream responseDataBAIS = new ByteArrayInputStream(responseData);
InputStreamReader responseDataISR = new InputStreamReader(responseDataBAIS, "UTF-8");
JSONParser responseDateJSONParser = new JSONParser();
Map<String, Object> responseResult = responseDateJSONParser.parseJSON(responseDataISR);
return responseResult;
}
public Map<String, Object> getResponseData() {
return responseData;
}
}
它被称为:
private Map<String, Object> fetchCelebrities() throws IOException {
GetAllCelebrities getAllCelebrities = new GetAllCelebrities("en");
getAllCelebrities.connect();
return getAllCelebrities.getResponseData();
}
private boolean performLogin() throws IOException {
String loginIDString = loginID.getText();
String loginPasswordString = loginPassword.getText();
Login login = new Login(loginIDString, loginPasswordString);
boolean loginResult = login.connect();
return loginResult;
}
答案 0 :(得分:1)
阅读所有这些代码有点难,但我会冒险根据服务器消息猜测。您已经在post put类中将方法设置为“PUT”,但服务器尚不支持该方法。
调试这些东西的最佳方法是使用模拟器中的网络监视器。它显示了流量,并且会使这些事情变得非常清楚