Cách thành ngữ để soạn URL hoặc URI trong Java là gì?


115

Làm cách nào để tạo URL hoặc URI trong Java? Có một cách thành ngữ, hoặc các thư viện dễ dàng làm điều này?

Tôi cần cho phép bắt đầu từ một chuỗi yêu cầu, phân tích / thay đổi các phần URL khác nhau (lược đồ, máy chủ, đường dẫn, chuỗi truy vấn) và hỗ trợ thêm và tự động mã hóa các tham số truy vấn.


7
Nâng cao câu hỏi rất lâu sau khi nó được đóng lại vì không rõ liệu một giải pháp không phổ biến cho vấn đề này có tồn tại hay không. Tôi đã tìm thấy điều này bằng cách googling cho 'lớp tham số URL java'.
dùng1445967

4
Ý định của tôi là tìm một trình xây dựng URL cho Java và ít nhất câu hỏi này hữu ích cho tôi.
lốc xoáy

Câu trả lời:


76

Kể từ Thành phần HTTP HTTP HTTPClient 4.1.3, từ hướng dẫn chính thức :

public class HttpClientTest {
public static void main(String[] args) throws URISyntaxException {
    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    qparams.add(new BasicNameValuePair("q", "httpclient"));
    qparams.add(new BasicNameValuePair("btnG", "Google Search"));
    qparams.add(new BasicNameValuePair("aq", "f"));
    qparams.add(new BasicNameValuePair("oq", null));
    URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
                                 URLEncodedUtils.format(qparams, "UTF-8"), null);
    HttpGet httpget = new HttpGet(uri);
    System.out.println(httpget.getURI());
    //http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
}
}

Chỉnh sửa: kể từ phiên bản 4.2 URIUtils.createURI()đã không được ủng hộ URIBuilder:

URI uri = new URIBuilder()
        .setScheme("http")
        .setHost("www.google.com")
        .setPath("/search")
        .setParameter("q", "httpclient")
        .setParameter("btnG", "Google Search")
        .setParameter("aq", "f")
        .setParameter("oq", "")
        .build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());

20
Điều này hoạt động, nhưng kể từ v4.2 URIUtils.createURI () đã không được chấp nhận để ủng hộ URIBuilder. Về mặt tích cực, URIBuilder này dường như có một phương thức addParameter () để việc xây dựng chuỗi yêu cầu ít nhất phải đơn giản hơn bây giờ.
stian

6
URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams);như @stian đã nói
vanduc1102

Println ở trên in như sau; google.com/ Quảng cáo
Berkan Ercan

61

Là tác giả, tôi có lẽ không phải là người tốt nhất để đánh giá xem trình tạo URL / URI của tôi có tốt không , nhưng ở đây vẫn là: https://github.com/mikaelhg/urlbuilder

Tôi muốn giải pháp hoàn chỉnh đơn giản nhất có thể với các phụ thuộc bằng không bên ngoài JDK, vì vậy tôi phải tự lăn.


6
Trông Mikael thật tuyệt, bạn đã nghĩ đến việc xuất bản nó cho maven trung tâm chưa? Tôi biết nó nhỏ nhưng làm cho việc sử dụng nó dễ dàng hơn. Tôi không thể tìm thấy một lớp tương tự ngoài JAX-RS. Việc thiếu phụ thuộc chắc chắn là một lợi thế.
Barry Pitman

Nó trông đẹp, nhưng vì nó là một trình xây dựng và do đó có thể thay đổi, tại sao chỉ có setters cho các tham số, nhưng không phải cho máy chủ, cổng, giao thức và đường dẫn? Và, tốt, không có getters cho những người cũng. CẬP NHẬT: Ồ, nó không thể thay đổi - setParameter tạo bản sao. Chà, vẫn sethost / setPort / ... có thể hoạt động theo cách tương tự. Hoặc, có lẽ, một phiên bản có thể thay đổi cũng sẽ rất hay.
mvmn

3
"giải pháp hoàn chỉnh đơn giản nhất có thể với sự phụ thuộc bằng không" - Âm thanh như bạn biết điều gì là quan trọng! Câu trả lời của bạn nên được chấp nhận. Bao gồm tất cả các HTTPClient (với tất cả các bản cập nhật phiên bản và thậm chí không tán thành chính API mà câu hỏi này đề cập đến) chỉ để xây dựng một url là điều tạo nên các ứng dụng bị lỗi nặng hàng đầu.
Stijn de Witt

2
Cuối cùng trên Maven Central, và tôi chỉ mất bốn năm để hoàn thành.
Mikael Gueck

@mikaelhg Cảm ơn bạn! Tôi cần chính xác trong thời điểm này!
Fabian Damken


29

Sử dụng HTTPClient hoạt động tốt.

protected static String createUrl(List<NameValuePair> pairs) throws URIException{

  HttpMethod method = new GetMethod("http://example.org");
  method.setQueryString(pairs.toArray(new NameValuePair[]{}));

  return method.getURI().getEscapedURI();

}

6
Đây là chức năng không dùng nữa. Có ai biết cách sử dụng gói Thành phần HTTP mới để làm điều tương tự không vì nó làm tôi bối rối.
Liên kết 19

3
Phiên bản 4x mới không hỗ trợ điều này nữa.
Joscha

13

Có rất nhiều thư viện có thể giúp bạn xây dựng URI (không phát minh lại bánh xe). Đây là ba để giúp bạn bắt đầu:


Java EE 7

import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();

org.apache.httpcomponents: httpclient: 4.5.2

import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();

org.springframework: spring-web: 4.2.5.RELEASE

import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();

Xem thêm: GIST> Kiểm tra trình tạo URI


2
EE 7 là câu trả lời đúng. Tất cả những gì bạn phải làm là kéo vào toàn bộ bộ thư viện EE, chọn triển khai JAX-RS, giải quyết xung đột phiên bản jax-rs và như một phần thưởng, bạn sẽ có một lớp UriBuilder tiện dụng hoạt động rất tốt. Sarcasm sang một bên, đây câu trả lời chính xác. :)
tekHedd


10

Sử dụng OkHttp

Đó là năm 2020 và có một thư viện rất nổi tiếng có tên OkHttp đã được đóng vai chính 35K lần trên GitHub. Với thư viện này, bạn có thể tạo một url như bên dưới:

import okhttp3.HttpUrl;

URL url = new HttpUrl.Builder()
    .scheme("http")
    .host("example.com")
    .port(4567)
    .addPathSegment("foldername/1234")
    .addQueryParameter("abc", "xyz")
    .build().url();

Tôi đã sửa một lỗi đánh máy, nó addPathSegment(không addPathSegments).
PapaFreud

1

Sau khi được đề nghị cho đề xuất lớp URL. Tôi sẽ lấy lời khuyên của người bình luận và đề xuất lớp URI thay thế. Tôi đề nghị bạn xem xét kỹ các hàm tạo cho một URI vì lớp này rất bất biến khi được tạo.
Tôi nghĩ rằng hàm tạo này cho phép bạn đặt mọi thứ trong URI mà bạn có thể cần.

URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)
          Constructs a hierarchical URI from the given components.

8
Nhưng nó không cung cấp chức năng để thực sự xây dựng và mã hóa chuỗi truy vấn từ một tập hợp các cặp giá trị tên.
Link19

4
Như thần đồng đã nói với Alan Partridge - người ta không thể có sự xuống cấp về tính bất biến, dù có hay không ;-) youtube.com/watch?v=_lvFns5Lubc
Stewart

Hàm tạo của URI thực hiện những điều khó chịu đối với đường dẫn. Xem blog.palominolabs.com/2013/10/03/ để biết chi tiết.
mpierce

1
Hãy để câu trả lời này là một ví dụ về cách KHÔNG làm điều này sau đó.
Mike Pone

1
Truy vấn chuỗi ... Cảm ơn Sun / Oracle về độ chi tiết. Chúng tôi sẽ chỉ thay thế tất cả các không gian bằng các ký hiệu cộng, mã hóa tất cả các tham số và liên kết tất cả chúng với nhau bằng các ký hiệu dấu và sau đó ... đập đầu vào bàn liên tục
Stijn de Witt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.