向 Java REST 中的路径参数添加值?

Adding value to path parameter in Java REST?

NOTICE UPDATE!!

The problem got solved and i added my own answer in the thread

简而言之,我试图添加参数 "scan_id" 值,但由于它是 POST 我无法直接在 url 路径中添加值。

使用我已有的代码,我将如何修改或添加以使 url 正确,也就是说,它接受我的 POST?

不知何故,我一直无法找到任何帮助我弄清楚我将如何去做的例子..

我知道如何使用负载执行 POST,使用参数执行 GET。但是 post 和 Params 让我很困惑。

感谢任何帮助。 (我想继续使用 HttpUrlConnection 除非提供了另一个示例,该示例还告诉我如何发送请求而不仅仅是配置路径。

我试过将它添加到负载中。 我已经尝试过 UriBuilder 但发现它与我的其余代码形成鲜明对比,所以我想寻求有关 HttpUrlConnection.

的帮助
URL url = new URL("http://localhost/scans/{scan_id}/launch");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("tmp_value_dont_mind_this", "432432");
        con.setRequestProperty("X-Cookie", "token=" + "43432");
        con.setRequestProperty("X-ApiKeys", "accessKey="+"43234;" + " secretKey="+"43234;");

        con.setDoInput(true);
        con.setDoOutput(true); //NOT NEEDED FOR GETS
        con.setRequestMethod("POST");
        con.setRequestProperty("Accept", "application/json");
        con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

                //First example of writing (works when writing a payload)
        OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
        writer.write(payload);
        writer.close();     

        //second attemp at writing, doens't work (wanted to replace {scan_id} in the url)
        DataOutputStream writer = new DataOutputStream(con.getOutputStream());
        writer.writeChars("scan_id=42324"); //tried writing directly
        //writer.write(payload);
        writer.close();     

异常:

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: http://localhost/scans/launch

我想要三个响应代码之一,因为这样我就知道 Url 是正确的:

200 Returned if the scan was successfully launched. 
403 Returned if the scan is disabled. 
404 Returned if the scan does not exist. 

我已经尝试了几次 url

localhost/scans/launch, 
localhost/scans//launch, 
localhost/scans/?/launch, 
localhost/scans/{scan_id}/launch,

正如所讨论的 here 解决方案是将内容类型更改为 application/x-www-form-urlencoded,但由于您已经在使用 application/json; charset=UTF-8(我假设这是您的项目的要求) 你没有选择重新设计整个东西。我建议你以下之一:

  • 添加另一个 GET 服务;
  • 添加内容类型为 application/x-www-form-urlencoded 的另一个 POST 服务;
  • 将此服务替换为上述服务之一。
  • (不知道在java中是否可行)

如果还有其他我不知道的解决方案,我不知道它们在多大程度上符合 HTTP 协议。

(More info)

希望我有所帮助!

为什么你不这样使用。由于需要做一个POSTHttpURLConnection,所以需要在打开连接后将参数写入连接。

String urlParameters  = "scan_id=42324";
byte[] postData       = urlParameters.getBytes(StandardCharsets.UTF_8);

DataOutputStream dataOutputStream  = new DataOutputStream(conn.getOutputStream());
dataOutputStream.write(postData);

或者如果你最后有launch,只需将上面的代码改成下面这样,

String urlParameters  = "42324/launch";
byte[] postData       = urlParameters.getBytes(StandardCharsets.UTF_8);

DataOutputStream dataOutputStream  = new DataOutputStream(conn.getOutputStream());
dataOutputStream.write(postData);
URL url = new URL("http://localhost/scans/{scan_id}/launch");

我觉得那条线很奇怪;看来您正在尝试使用 URL 而您打算使用 URI Template.

的行为

确切的语法将取决于您选择的模板实现;使用 Spring libraries 的实现可能如下所示:

import org.springframework.web.util.UriTemplate;
import java.net.url;

// Warning - UNTESTED code ahead
UriTemplate template = new UriTemplate("http://localhost/scans/{scan_id}/launch");
Map<String,String> uriVariables = Collections.singletonMap("scan_id", "42324");
URI uri = template.expand(uriVariables);
URL url = uri.toURL();

所以在朋友和这里的每个人的帮助下我解决了我的问题。

下面的代码是整个class中的所有代码,一点一点解释。在底部你有完整的 class 及其所有语法等,它接受参数和 returns 一个字符串。

在 HTTP 请求中有特定的部分。 在我的案例中,这些部分包括请求 headers、Url 中的参数和有效负载。

根据 API,API 需要的某些变量需要进入各自的类别。

My ORIGINAL URL looked like this: "http://host:port/scans/{scan_id}/export?{history_id}"
I CHANGED to: "https://host:port/scans/" + scan_Id + "/export?history_id=" + ID;

和我正在调用的 API 需要有效载荷中的参数 "format" 和一个值。

String payload = "{\"format\" : \"csv\"}";

因此,使用我的新 URL 我打开了一个连接并设置了我需要设置的请求 headers。

        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

在发起GET请求时,setDoOutput应该被注释掉。

        con.setDoInput(true);
        con.setDoOutput(true); 
        con.setRequestMethod("POST");
        con.setRequestProperty("Accept", "application/json");
        con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        con.setRequestProperty("X-Cookie", "token=" + token);
        con.setRequestProperty("X-ApiKeys", "accessKey="+"23243;" +"secretKey="+"45543;");

这里我写入payload

        //WRITING THE PAYLOAD to the http call
        OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
        writer.write(payload);
        writer.close();

在我写入有效载荷后,我读取了我返回的任何响应(这取决于调用,当我进行文件下载(GET 请求)时,我没有读取响应,因为我已经通过另一段代码读取响应)。

我希望这对可能遇到此话题的任何人有所帮助。

public String requestScan(int scan_Id, String token, String ID) throws MalformedInputException, ProtocolException, IOException {

    try {
        String endpoint = "https://host:port/scans/" + scan_Id + "/export?history_id=" ID;
        URL url = new URL(endpoint);

        String payload= "{\"format\" : \"csv\"}";

        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

        con.setDoInput(true);
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        con.setRequestProperty("Accept", "application/json");
        con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        con.setRequestProperty("X-Cookie", "token=" + token);
        con.setRequestProperty("X-ApiKeys", "accessKey="+"324324;" + 
                "secretKey="+"43242;");

        //WRITING THE PAYLOAD to the http call
        OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
        writer.write(payload);
        writer.close();

        //READING RESPONSE
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        StringBuffer jsonString = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
            jsonString.append(line);
        }
        br.close();
        con.disconnect();

        return jsonString.toString();
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage());
    }
}