2014-10-18 44 views
0

我需要通過網絡發送字符串,並且我在Spring Boot的REST控制器的另一端獲取它。作爲字節[]發送的字符串內容將其內容作爲查詢字符串轉義

我有以下行發送的數據:

byte[] content = sw.toString().getBytes(StandardCharsets.UTF_8); //sw is StringWriter 
httpUrlConnection = (HttpURLConnection)new URL("http://127.0.0.1:8080/upload").openConnection(); 
httpUrlConnection.setDoInput(false); 
httpUrlConnection.setDoOutput(true); 
httpUrlConnection.setRequestMethod("POST"); 
httpUrlConnection.setFixedLengthStreamingMode(content.length); 
httpUrlConnection.connect(); 
httpUrlConnection.getOutputStream().write(content); 
httpUrlConnection.getOutputStream().flush(); 

而且我收到這樣的:

@RequestMapping(value="/upload", method = RequestMethod.POST) 
public ResponseEntity<String> upload(@RequestBody byte[] uploadedData) 
    throws NoSuchAlgorithmException, InvalidKeyException, IOException { 
    if(uploadedData == null) { 
    log.info("Uploaded data was null."); 
    return new ResponseEntity<String>("Data was null after upload.", HttpStatus.INTERNAL_SERVER_ERROR); 
    } 

    String receivedData = new String(uploadedData, StandardCharsets.UTF_8); 
    log.info("" + receivedData); 

但是,當我要送這是... ...

-----BEGIN CERTIFICATE REQUEST----- 
MIIB0DCCATkCAQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9u 
IG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNV 
BAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91 
bmN5Y2FzdGxlLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqE+pEyKS 
21JXgeldS83E+SSmQ4s2xYPqV7Yw2ebUKsxnbBz1KcXHdHS1MJ9PYzBJgogdigZW 
6hEQ83edP/Ay/EQzGqeKUzFqNEsQh3PSdbF9N5k7b81tQHUbfIbNu1ofSBNa/Eit 
MkOj1NAmwivpW0AA8aPZhGzYLYWcp0lsC78CAwEAAaAAMA0GCSqGSIb3DQEBBQUA 
A4GBAB0p0ySmfMkm3z8H4P8WwWJ8bMO2RNXEx0i9fU2ncJfdY0zEPYvM6zpUhwJP 
T9DsQBPdSy+VLbJ/PtYoiKIcupd+vriGYn3mqckXy7RBLqpiVsnw1rGE28oG4I9N 
u0p2AwDuC+KNuHgtrGxYrRnFTRKZpj2AoGuW1a6eSaNOhPeq 
-----END CERTIFICATE REQUEST----- 

我所得到的是這樣的:

-----BEGIN+CERTIFICATE+REQUEST-----%0D%0AMIIB0DCCATkCAQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9u%0D%0AIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNV%0D%0ABAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91%0D%0AbmN5Y2FzdGxlLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqE+pEyKS%0D%0A21JXgeldS83E+SSmQ4s2xYPqV7Yw2ebUKsxnbBz1KcXHdHS1MJ9PYzBJgogdigZW%0D%0A6hEQ83edP%2FAy%2FEQzGqeKUzFqNEsQh3PSdbF9N5k7b81tQHUbfIbNu1ofSBNa%2FEit%0D%0AMkOj1NAmwivpW0AA8aPZhGzYLYWcp0lsC78CAwEAAaAAMA0GCSqGSIb3DQEBBQUA%0D%0AA4GBAB0p0ySmfMkm3z8H4P8WwWJ8bMO2RNXEx0i9fU2ncJfdY0zEPYvM6zpUhwJP%0D%0AT9DsQBPdSy+VLbJ%2FPtYoiKIcupd+vriGYn3mqckXy7RBLqpiVsnw1rGE28oG4I9N%0D%0Au0p2AwDuC+KNuHgtrGxYrRnFTRKZpj2AoGuW1a6eSaNOhPeq%0D%0A-----END+CERTIFICATE+REQUEST-----%0D%0A= 

這不好,因爲它殺死了PEM解析器。

不過,我可以通過以下變換克服這個問題,而字符串變成可解析...

receivedData = receivedData.replace("-----BEGIN+CERTIFICATE+REQUEST-----", "-----BEGIN CERTIFICATE REQUEST-----"); 
    receivedData = receivedData.replace("-----END+CERTIFICATE+REQUEST-----", "-----END CERTIFICATE REQUEST-----"); 
    receivedData = receivedData.replace("%0D%0A", "\r\n"); 
    receivedData = receivedData.replace("%2F", "/"); 
    receivedData = receivedData.substring(0, receivedData.length()-1); 

在這種情況下,解析成功...

2014-10-18 16:26:43.864 INFO 2432 --- [nio-8080-exec-1] demo.HelloController      : PemParser returned: [email protected] 
2014-10-18 16:26:43.870 INFO 2432 --- [nio-8080-exec-1] demo.HelloController      : SUCCESS 

..但我認爲這不是一種真正可行的做事方式,因爲它看起來不太穩定。一定有更好的方法。我嘗試了URLEncoder.decode(receivedData, "UTF-8");,但它從實際數據中刪除了+個字符,這也不好,因爲它使數據不可解析。

當我通過網絡發送String時,有沒有人有任何有用的想法來防止這個URL escaping

+0

您執行了哪些診斷?你是否通過(比如說)Wireshark查看了發送的內容?你記錄了'sw'嗎? – 2014-10-18 14:39:52

+0

@JonSkeet'sw'工作得很好,沒有任何麻煩,並記錄了記錄的內容。也就是說,客戶端的數據有效。只有在我收到另一邊的字符串後,在這方面纔是一團糟。不過,我沒有檢查Wireshark。 – EpicPandaForce 2014-10-18 14:44:28

+0

@JonSkeet ...當我沒有在只有一臺帶有本地主機的計算機上進行測試時,我不得不使用Wireshark進行檢查,因爲我沒有正確訪問路由器。這樣我沒有使用我的網絡接口,因此無法正確記錄數據包。我會在稍後看看。 – EpicPandaForce 2014-10-18 14:51:05

回答

1

那麼,我仍然不知道的答案爲什麼發生了,但我做了一個解決方法。

而不是僅僅發送在String字節[]內容,我根據http://docs.oracle.com/javaee/7/tutorial/doc/jsonp003.htmhttps://jsonp.java.net/index.html包裹在一個JSON對象的數據。

JsonObject model = Json.createObjectBuilder().add("data", sw.toString()).build(); 

httpsUrlConnection = (HttpsURLConnection)new URL("http://127.0.0.1:8443/upload").openConnection(); 

httpsUrlConnection.setDoInput(true); 
httpsUrlConnection.setDoOutput(true); 
httpsUrlConnection.setRequestProperty("Content-Type", "application/json"); 
httpsUrlConnection.setRequestMethod("POST"); 
httpsUrlConnection.connect(); 
try(JsonWriter jsonWriter = Json.createWriter(httpsUrlConnection.getOutputStream())) 
{ 
    jsonWriter.write(model); 
} 
httpsUrlConnection.getOutputStream().flush(); 
System.out.println("Response code: " + httpsUrlConnection.getResponseCode()); 

之後,在春季啓動的一面,我把它,這樣我就收到JSON對象按https://stackoverflow.com/a/8946142/2413303

public class DataObject { 
    private String data; 

    public String getData() { 
    return data; 
    } 

    public void setData(String data) { 
    this.data = data; 
    } 
} 

並在控制器:

@RequestMapping(value="/upload", method = RequestMethod.POST, consumes="application/json") 
    public ResponseEntity<String> upload(@RequestBody DataObject uploadedData) 
    throws NoSuchAlgorithmException, InvalidKeyException, IOException { 
    if(uploadedData == null) { 
     log.info("Uploaded data was null."); 
     return new ResponseEntity<String>("Data was null after upload.", HttpStatus.INTERNAL_SERVER_ERROR); 
    } 
    String receivedData = uploadedData.getData(); 
    log.info("" + receivedData); 

這方式字符不逃脫:

2014-10-20 13:03:15.550 INFO 6924 --- [nio-8443-exec-3] demo.HelloController      : -----BEGIN CERTIFICATE REQUEST----- 

編輯:我被告知,問題是沒有內容類型設置,春天默認爲application/x-www-form-urlencoded,因爲它應該是application/octet-stream

EDIT2:隨着octet-stream,送過來逃脫\r\n\\r\\n,以及之前和字符串出於某種原因後添加一個"。不知道爲什麼。

相關問題