自建Hadoop MiniCluster发起PUT写入请求返回405错误如何解决
错误原因
- WebHDFS的请求路径错误,HDFS REST API的标准前缀是
/webhdfs/v1,你代码中使用的/webapps/v1是无效路径,NameNode内置的Jetty服务没有为该路径绑定PUT方法的处理逻辑,所以直接返回405错误。 - URL参数分隔符使用错误,文件路径和第一个请求参数之间需要用
?连接,你使用了&导致op=CREATE参数没有被NameNode正确识别。 - WebHDFS的CREATE操作默认会返回307临时重定向响应,引导请求跳转到实际存储数据的DataNode地址,
HttpURLConnection默认不会自动跟随PUT类型请求的重定向,需要额外手动处理。
修正后代码
private static void putTest() throws IOException { System.out.println("putTest : Entry"); // 修正路径前缀和参数分隔符,添加overwrite参数避免文件已存在时报错 String nnRequestUrl = "http://localhost:50070/webhdfs/v1/longdata.txt?op=CREATE&overwrite=true"; HttpURLConnection con = (HttpURLConnection) new URL(nnRequestUrl).openConnection(); con.setRequestMethod("PUT"); con.setDoOutput(true); // 手动处理307重定向 int responseCode = con.getResponseCode(); if (responseCode == 307) { String dataNodeUrl = con.getHeaderField("Location"); con = (HttpURLConnection) new URL(dataNodeUrl).openConnection(); con.setRequestMethod("PUT"); con.setDoOutput(true); } // 向DataNode写入数据 con.getOutputStream().write("Hey Guys".getBytes(StandardCharsets.UTF_8)); System.out.println("最终请求响应码:" + con.getResponseCode()); Map<String, List<String>> headers = con.getHeaderFields(); for (String header : headers.keySet()) { System.out.println(header + ": " + headers.get(header)); } System.out.println("putTest : Exit"); }
本地验证方法
修改代码后如果仍有问题,可以先执行curl命令验证MiniCluster的WebHDFS服务是否正常:curl -i -X PUT "http://localhost:50070/webhdfs/v1/longdata.txt?op=CREATE&overwrite=true"
正常情况下会返回307重定向响应,Location字段即为DataNode的写入地址。
内容的提问来源于stack exchange,提问作者Yesh Gowda
相关产品推荐
相关产品推荐

