Estou tentando enviar uma solicitação de postagem para um url usando HttpURLConnection (para usar cUrl em java). O conteúdo da solicitação é xml e, no ponto final, o aplicativo processa o xml e armazena um registro no banco de dados e, em seguida, envia de volta uma resposta na forma de string xml. O aplicativo está hospedado no apache-tomcat localmente.
Quando executo este código no terminal, uma linha é adicionada ao banco de dados conforme o esperado. Mas uma exceção é lançada da seguinte maneira ao obter o InputStream da conexão
java.io.FileNotFoundException: http://localhost:8080/myapp/service/generate
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1401)
at org.kodeplay.helloworld.HttpCurl.main(HttpCurl.java:30)
Aqui está o código
public class HttpCurl {
public static void main(String [] args) {
HttpURLConnection con;
try {
con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
File xmlFile = new File("test.xml");
String xml = ReadWriteTextFile.getContents(xmlFile);
con.getOutputStream().write(xml.getBytes("UTF-8"));
InputStream response = con.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(response));
for (String line ; (line = reader.readLine()) != null;) {
System.out.println(line);
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
É confuso porque a exceção é rastreada até a linha InputStream response = con.getInputStream();
e não parece haver nenhum arquivo envolvido para uma FileNotFoundException.
Quando tento abrir uma conexão com um arquivo xml diretamente, ele não lança essa exceção.
O aplicativo de serviço usa o framework spring e Jaxb2Marshaller para criar o xml de resposta.
A classe ReadWriteTextFile é tirada daqui
Obrigado.
Edit: Bem, ele salva os dados no banco de dados e envia de volta um código de status de resposta 404 ao mesmo tempo.
Eu também tentei fazer um curl usando php e imprimir o CURLINFO_HTTP_CODE
que acabou sendo 200.
Alguma ideia de como faço para depurar isso? O serviço e o cliente estão no servidor local.
Resolvido: eu poderia resolver o problema após consultar uma resposta no próprio SO.
Parece que HttpURLConnection sempre retorna a resposta 404 ao se conectar a um url com uma porta não padrão.
Adicionar essas linhas resolveu
con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
con.setRequestProperty("Accept","*/*");
Respostas:
Não sei sobre sua combinação Spring / JAXB, mas o serviço da web REST médio não retornará um corpo de resposta no POST / PUT, apenas um status de resposta . Você gostaria de determiná-lo em vez do corpo.
Substituir
de
Todos os códigos de status disponíveis e seus significados estão disponíveis na especificação HTTP, conforme linkado anteriormente. O próprio serviço da web também deve vir junto com alguma documentação que apresenta uma visão geral de todos os códigos de status suportados pelo serviço da web e seu significado especial, se houver.
Se o status começar com
4nn
ou5nn
, você gostaria de usargetErrorStream()
para ler o corpo da resposta, que pode conter os detalhes do erro.fonte
getErrorStream()
como sugerido. Ele lança uma NullPointerExceptionnew InputStreamReader(con.getErrorStream())
.URLConnection
problemática mais genérica . Eu me pergunto por que os caras do Java não implementaram simplesmentegetInputStream()
aoHttpUrlConnection
longo das linhas dereturn responseCode == 200 ? super.getInputStream() : this.getErrorStream()
. Mas de qualquer maneira; resposta informativa, +1.FileNotFound
é apenas uma exceção infeliz usada para indicar que o servidor da web retornou um 404.fonte
getResponseCode()
antes de ligargetInputStream()
.Para qualquer pessoa com esse problema no futuro, o motivo é porque o código de status era 404 (ou no meu caso era 500). Parece que a
InpuStream
função gerará um erro quando o código de status não for 200.No meu caso, eu controlo meu próprio servidor e estava retornando um código de status 500 para indicar que ocorreu um erro. Apesar de eu também enviar um corpo com uma mensagem em string detalhando o erro, o
inputstream
lançou um erro independentemente de o corpo ser completamente legível.Se você controlar seu servidor, suponho que isso possa ser resolvido enviando a você mesmo um código de status 200 e, em seguida, tratando de qualquer resposta de erro de string.
fonte
Para qualquer outra pessoa que tenha problemas com isso, o mesmo aconteceu comigo enquanto tentava enviar um cabeçalho de solicitação SOAP para um serviço SOAP. O problema era uma ordem errada no código, solicitei o fluxo de entrada antes de enviar o corpo XML. No código cortado abaixo, a linha
InputStream in = conn.getInputStream();
veio imediatamente após aByteArrayOutputStream out = new ByteArrayOutputStream();
qual está a ordem incorreta das coisas.FileNotFound
neste caso, foi uma forma infeliz de codificar o código de resposta HTTP 400.fonte
new ByteArrayOutputStream()
não tem nada a ver com isso. O problema é a ordem entregetInputStream()
egetResponseCode()
.FileNotFound, neste caso, significa que você obteve um 404 do seu servidor - será que o servidor não gosta de solicitações "POST"?
fonte
A solução:
basta alterar localhost para o IP do seu PC
, se você quiser saber o seguinte: Windows + r> cmd> ipconfig
exemplo: http: // 192.168.0.107 /directory/service/program.php?action=sendSomething
apenas substituir 192.168 .0.107 para seu próprio IP (não tente 127.0.0.1 porque é o mesmo que localhost )
fonte
Por favor, mude
Para
fonte