2017-05-25 36 views
0

首先,是的,有這個確切的前提SO有多個問題。但是沒有任何答案適用於我,所以我會問我的具體問題。本地webserice的FileNotFoundException在HttpURLConnection.getInputStream()

我有一個本地運行的web服務。這個web服務有一個方法可以讓你嘗試登錄。如果你成功了,它會發回用戶信息。如果你不這樣做,你會得到一個無效的用戶對象。

@Path("/UserService") 
public class UserService { 
    Dao dao = new Dao(); 

    @POST 
    @Consumes(MediaType.APPLICATION_XML) 
    @Path("/login") 
    @Produces(MediaType.APPLICATION_XML) 
    public User login(final LoginBean params){ 
     //return new User(); 

     User u = new User(); 
     u.setEmail(params.email); 
     u.setPassword(params.password); 
     return dao.login(u); 
    } 
} 

這個特定的方法在Postman中工作正常。我稱之爲,獲得200響應,並將一個完整的用戶對象作爲xml。

但是,當我從我的代碼調用它時,它會在conn.getInputStream()行引發FileNotFoundException;

public class UserDAO { 

    public static User login(User user) { 
     String uri = "http://192.168.2.22:8080/Roommanagement/rest/UserService/login"; 
     try { 
      URL url = new URL(uri); 

      HttpURLConnection conn= (HttpURLConnection) url.openConnection();   
      conn.setDoOutput(true); 
      conn.setInstanceFollowRedirects(false); 
      conn.setRequestMethod("POST"); 
      //conn.setRequestProperty("Accept", "application/xml"); 
      conn.setRequestProperty("Content-Type", "application/xml"); 
      //conn.setRequestProperty("charset", "utf-8"); 
      //conn.setRequestProperty("Content-Length", Integer.toString(postDataLength)); 
      conn.setUseCaches(false); 

      JAXBContext jc = JAXBContext.newInstance(User.class); 

      jc.createMarshaller().marshal(user, conn.getOutputStream()); 

      //XMLEncoder xmlE = new XMLEncoder(conn.getOutputStream()); 
      //xmlE.writeObject(user); 
      //xmlE.close(); 

      JAXBContext jc = JAXBContext.newInstance(User.class); 
      java.io.InputStream streamXML; 
      streamXML = conn.getInputStream(); 
      User returnedUser = 
      (User) jc.createUnmarshaller().unmarshal(streamXML); 
      conn.disconnect(); 
      return returnedUser; 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (JAXBException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return new User(); 
    } 
} 

你可以在註釋掉的行中看到我嘗試過的一些東西,但它們沒有任何區別。

我在做什麼錯?我認爲服務本身沒有問題,因爲我的所有手動電話都按預期工作。

+0

你必須使用JAXB同時爲輸入和輸出。 'XMLEncoder'用於bean序列化,它產生完全不同於JAXB轉換的XML。 – VGR

+0

我試過了,但我得到了完全相同的問題。如果它有所作爲,我可以更新問題中的代碼。 –

+0

嘗試調試以在getInputStream之前添加'conn.getResponseCode()'。在大多數情況下,當getInputStream引發'FileNotFoundException'實際發生的事情時:您從服務器獲得了404。在這種情況下,請繼續使用'getErrorStream'進行調試。你正在調用RestService,你不(休息/ UserService /登錄)?在這種情況下,後處理方法可能只響應http-header和沒有http-body,因爲它是post方法的其餘默認值(據我所知)。 –

回答

2

我在這裏看到一個潛在的問題:
您的操作節選一個LoginBean實例,但你提供它User實例:

public User login(final LoginBean params){ 

public static User login(User user) { 
    .... 
    jc.createMarshaller().marshal(user, conn.getOutputStream()); 
1

許多事情都可能發生。

您必須做的第一件事就是獲取響應代碼並對其進行測試。

con.getResponseCode(); 

在嘗試轉換爲XML之前獲取內容類型是一種很好的做法。只需用純字符串打印即可。

根據收到的回覆代碼處理回覆。這裏可以使用一些代碼作爲例子。

if ((200 <= con.getResponseCode() && con.getResponseCode() <= 299)) { 
     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((con.getInputStream()))); 
     String response = new String(); 
     for (String line; (line = bufferedReader.readLine()) != null; response += line); 
     System.out.println(response); 
    } else { 
     System.out.println(); 
     Map<String, List<String>> map = con.getHeaderFields(); 
     for (Map.Entry<String, List<String>> entry : map.entrySet()) { 
      if (entry.getKey() == null) { 
       System.out.println(entry.getValue()); 
      } else { 
       System.out.println(entry.getKey() + ":" + entry.getValue()); 
      } 
     } 
     System.out.println(); 
     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((con.getErrorStream()))); 
     String response = new String(); 
     for (String line; (line = bufferedReader.readLine()) != null; response += line); 
     System.out.println(response); 
     throw new WebServiceException(response); 
    } 
} 
0

我想你錯過了實際HTTP請求的代碼。您需要調用connect方法來進行實際的請求。

conn.connect() 

其餘的代碼看起來不錯。