代号一:405 Method Not Allowed 错误

Posted

技术标签:

【中文标题】代号一:405 Method Not Allowed 错误【英文标题】:Codename One: 405 Method Not Allowed error 【发布时间】:2017-03-19 13:40:19 【问题描述】:

我一直在 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 错误?

编辑:我在这里添加我的cient 端代码: (请注意,这个处理来自服务器的 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;

【问题讨论】:

您好,能否提供您的手机代号一个连接请求代码? 我已经编辑了我的问题并添加了我的客户端源代码。 【参考方案1】:

阅读所有这些代码有点困难,但我会根据服务器消息进行猜测。您已在 post put 类中将方法设置为“PUT”,但服务器尚不支持。

调试这些东西的最佳方法是使用模拟器中的网络监视器。它显示了流量,并且会让这些事情变得很清楚

【讨论】:

而实际上调用了服务器。我做了一个调试,它执行到最后一个 println 语句。 我特意设置了"connectionRequest.setHttpMethod("POST");"和 connectionRequest.setPost(true);所以它不能是 PUT 连接。 (PostPutConnection 是 Post 和 Put 连接的公共类,但在这种情况下,它被专门称为 Post 连接。)并且...服务器 println 显示该方法是 INDEED CALLED,直到最后一个 println 语句。那么,如果确实调用了该方法并返回 200,那么是什么导致 Codename 将其视为 405? 你让我在模拟器中调试。但它在模拟器中运行良好。那么,解决这个问题的方法是什么? 因为确实调用了服务器端(我已经测试过很多次了)并且打印输出“This is print out!!!”证明了这一点(见上文),我认为客户期待某种 MIME 类型。 Codename One 期望的响应 mimetype 是什么? (同样,问题只存在于真正的 Android 设备上,但模拟器运行良好。) 好的。问题已解决。 POST 连接没有任何问题。调用 POST 连接后,它会调用 GET 连接,这就是问题所在。除了“connectionRequest.setHttpMethod(“GET”)”之外,我还必须调用“connectionRequest.setPost(false)”。这解决了整个问题。

以上是关于代号一:405 Method Not Allowed 错误的主要内容,如果未能解决你的问题,请参考以下文章

postman发送post请求,报405 Method Not Allowed

跨域405(Method Not Allowed)问题

这是啥 405 Method Not Allowed svn 错误?

jersey中的405错误 method not allowed

HTTP Status 405 - HTTP method POST is not supported by this URL另外一种原因

为啥此请求返回 405 Method Not Allowed?