2013-10-23 14 views
14

Trong hầu hết các mã tôi làm việc với đó là những thứ khủng khiếp như:Có cách nào đúng để tạo URL không?

String url = "../Somewhere/SomeServlet?method=AMethod&id="+object.getSomething()+ "&aParam="+object.getSomethingElse()); 

hoặc - thậm chí tệ hơn:

String url = "Somewhere/Here/Something.jsp?path="+aFile.toString().replace("\\","/")+ "&aParam="+object.getSomethingElse()); 

Có cách nào quyền:

  1. Tạo URL mới (hoặc là URI).
  2. Thêm thông số thoát đúng vào nó.
  3. Thêm đường dẫn tệp được định dạng tốt trong các thông số đó.
  4. Giải quyết nó thành chuỗi.

Về cơ bản - quá dễ dàng để chỉ xây dựng chuỗi hơn là thực hiện đúng cách. Có cách nào để làm điều đó đúng cách dễ dàng như việc xây dựng chuỗi không?

Added

Để rõ ràng - và sau một chút suy nghĩ - Tôi cho rằng tôi đang tìm kiếm một cái gì đó như:

String s = new MyThing() 
    .setPlace("Somewhere/Something.jsp") 
    .addParameter(aName,aValue) 
    .addParameter(aName,aFile) 
    .toString(); 

để nó sẽ đối phó với tất cả các khó chịu thoát và thêm "?"/"&" và thay đổi "\" thành "/" thay vì sử dụng "\" cho các tệp, v.v.

Nếu tôi phải viết một bản thân (ví dụ: Apache không phải là tùy chọn) kỹ thuật es để thoát đúng các phần khác nhau. Tôi có nghĩa là những thứ như thoát "" trong các tham số là "." trong khi thoát "" ở những nơi khác "% 20".

+1

Tôi nghĩ rằng điều này dường như tương tự. http://stackoverflow.com/questions/1861620/is-there-a-java-package-to-handle-building-urls –

+0

Ngoài ra, http://stackoverflow.com/questions/883136/is- có-a-tốt-url-builder-cho-java – siledh

Trả lời

5

Tôi đã viết nó lên, bạn có thể thay đổi nó ở nơi bạn muốn thêm chức năng. Nó không sử dụng bất kỳ tài nguyên bên ngoài, cho tôi biết nếu tôi đã xem xét một cái gì đó!

Về cơ bản, nó là một trình bao bọc cho lớp URI cho phép bạn dễ dàng thêm các thư mục con và tham số vào URI. Bạn có thể đặt các giá trị mặc định nếu bạn không quan tâm đến một số thứ.

Chỉnh sửa: Tôi đã thêm tùy chọn sử dụng URI tương đối (theo câu hỏi của bạn).

public class Test { 
    public static void main(String[] args) throws URISyntaxException, 
      MalformedURLException { 
     URLBuilder urlb = new URLBuilder("www.example.com"); 
     urlb.setConnectionType("http"); 
     urlb.addSubfolder("somesub"); 
     urlb.addSubfolder("anothersub"); 
     urlb.addParameter("param lol", "unknown"); 
     urlb.addParameter("paramY", "known"); 
     String url = urlb.getURL(); 
     System.out.println(url); 


     urlb = new URLBuilder(); 
     urlb.addSubfolder("servlet"); 
     urlb.addSubfolder("jsp"); 
     urlb.addSubfolder("somesub"); 
     urlb.addSubfolder("anothersub"); 
     urlb.addParameter("param lol", "unknown"); 
     urlb.addParameter("paramY", "known"); 
     String relUrl = urlb.getRelativeURL(); 
     System.out.println(relUrl); 
    } 
} 

class URLBuilder { 
    private StringBuilder folders, params; 
    private String connType, host; 

    void setConnectionType(String conn) { 
     connType = conn; 
    } 

    URLBuilder(){ 
     folders = new StringBuilder(); 
     params = new StringBuilder(); 
    } 

    URLBuilder(String host) { 
     this(); 
     this.host = host; 
    } 

    void addSubfolder(String folder) { 
     folders.append("/"); 
     folders.append(folder); 
    } 

    void addParameter(String parameter, String value) { 
     if(params.toString().length() > 0){params.append("&");} 
     params.append(parameter); 
     params.append("="); 
     params.append(value); 
    } 

    String getURL() throws URISyntaxException, MalformedURLException { 
     URI uri = new URI(connType, host, folders.toString(), 
       params.toString(), null); 
     return uri.toURL().toString(); 
    } 

    String getRelativeURL() throws URISyntaxException, MalformedURLException{ 
     URI uri = new URI(null, null, folders.toString(), params.toString(), null); 
     return uri.toString(); 
    } 
} 

Output:

Absolute

http://www.example.com/somesub/anothersub?param%20lol=unknown&paramY=known

tương đối

/servlet/jsp/somesub/anothersub param% 20lol = chưa biết & paramY = tiếng

+0

Cuối cùng tôi đã sử dụng một biến thể của kỹ thuật này [như thế này] (http://stackoverflow.com/a/19541585/823393). – OldCurmudgeon

-2

recomendations

private final String BASE_URL = Properties.getProperty("base-url"); 

private Map propertiesMap; // = new HashMap<String,String>(); 

và trong các mã để xây dựng các URL.

public String buildURL(){ 
    StringBuilder builder = new StringBuilder(); 
    builder.append(BASE_URL); 
    //for each property, append it 

    return builder.toString(); 

} 
+0

Downvoting, bởi vì đây chỉ là một nửa nướng mã mà lại phát minh ra bánh xe. Ngoài ra nó không giải quyết tất cả các yêu cầu của OP. –

12

Bạn có thể sử dụng Apache URIBuilder

Mẫu mã:? Full Apache Example

UriBuilder builder = new UriBuilder() 
    .setScheme("http") 
    .setHost("apache.org") 
    .setPath("/shindig") 
    .addParameter("hello world", "foo&bar") 
    .setFragment("foo"); 
builder.toString(); 

Output: http://apache.org/shindig?hello+world=foo%26bar#foo

+0

Vui lòng cập nhật setAuthority không còn hợp lệ – Olayinka

+0

Đó là 'URIBuilder', không phải' UriBuilder'. URL cuối cùng không hợp lệ và tôi sẽ xóa liên kết đến ví dụ đó. – ooi

1

Tôi thích gợi ý của @ Jeroen nhưng nó không hoàn toàn làm tất cả những gì tôi muốn, bằng cách sử dụng ý tưởng thu thập các phần với nhau nd sau đó sử dụng một URI phát triển kết quả cuối cùng tôi cùng nhau đưa giải pháp này mà dường như làm những gì tôi muốn:

public class URLBuilder { 
    // The scheme - http 
    private String scheme = null; 
    // The user - user 
    private String user = null; 
    // The host - example.com 
    private String host = null; 
    // The port - 8080 
    private int port = -1; 
    // The paths - /Path/To/Somewhere/index.jsp 
    private final ArrayList<String> paths = new ArrayList<String>(); 
    // The parameters - ?a=b&c=d 
    private final ArrayList<Pair<String, String>> queries = new ArrayList<Pair<String, String>>(); 
    // The fragment - #n 
    private String fragment = null; 

    public URLBuilder addQuery(String name, String value) { 
    queries.add(new Pair(name, value)); 
    return this; 
    } 

    public URLBuilder addQuery(String name, long value) { 
    addQuery(name, String.valueOf(value)); 
    return this; 
    } 

    public URLBuilder addQuery(String name, File file) { 
    addQuery(name, file.toURI().getPath()); 
    return this; 
    } 

    public URLBuilder addPath(String path) { 
    paths.add(path); 
    return this; 
    } 

    @Override 
    public String toString() { 
    // Build the path. 
    StringBuilder path = new StringBuilder(); 
    for (String p : paths) { 
     path.append("/").append(p); 
    } 
    // Build the query. 
    StringBuilder query = new StringBuilder(); 
    String sep = ""; 
    for (Pair<String, String> p : queries) { 
     query.append(sep).append(p.p).append("=").append(p.q); 
     sep = "&"; 
    } 
    String url = null; 
    try { 
     URI uri = new URI(
       scheme, 
       user, 
       host, 
       port, 
       path.length() > 0 ? path.toString() : null, 
       query.length() > 0 ? query.toString() : null, 
       fragment); 
     url = uri.toString(); 
    } catch (URISyntaxException ex) { 
     Logger.getLogger(URLBuilder.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    return url; 
    } 

    /** 
    * @param host the host to set 
    * @return this 
    */ 
    public URLBuilder setHost(String host) { 
    this.host = host; 
    return this; 
    } 

    /** 
    * @param scheme the scheme to set 
    * @return this 
    */ 
    public URLBuilder setScheme(String scheme) { 
    this.scheme = scheme; 
    return this; 
    } 

    /** 
    * @param user the user to set 
    * @return this 
    */ 
    public URLBuilder setUser(String user) { 
    this.user = user; 
    return this; 
    } 

    /** 
    * @param port the port to set 
    * @return this 
    */ 
    public URLBuilder setPort(int port) { 
    this.port = port; 
    return this; 
    } 

    /** 
    * @param fragment the fragment to set 
    * @return this 
    */ 
    public URLBuilder setFragment(String fragment) { 
    this.fragment = fragment; 
    return this; 
    } 

    public static void main(String args[]) { 
    try { 
     URLBuilder url = new URLBuilder(); 
     System.out.println(url.toString()); 
     url.setFragment("fragment"); 
     System.out.println(url.toString()); 
     url.setHost("host.com"); 
     System.out.println(url.toString()); 
     url.addPath("APath"); 
     System.out.println(url.toString()); 
     url.addPath("AnotherPath"); 
     System.out.println(url.toString()); 
     url.addQuery("query1", "param1"); 
     System.out.println(url.toString()); 
     url.addQuery("query 2", "param 2"); 
     System.out.println(url.toString()); 
     url.addQuery("file", new File("Hello World.txt")); 
     System.out.println(url.toString()); 
    } catch (Throwable t) { 
     t.printStackTrace(System.err); 
    } 
    } 

} 
+0

Bạn có thể làm rõ chức năng nào bạn đã thêm vào không? Vui vì tôi có thể giúp :) –

+0

@JeroenVannevel - Tôi đã thêm xử lý 'File' làm truy vấn và sử dụng hoàn toàn hơn lớp' URI'. Tôi dự định đánh dấu câu trả lời của bạn là chính xác vì nó đã truyền cảm hứng cho người xây dựng của tôi. Tôi đang chờ đợi những gợi ý muộn nhưng đầy cảm hứng. – OldCurmudgeon

4

Bạn cũng có thể sử dụng lò xo UriComponentsBuilder

UriComponentsBuilder 
    .fromUriString(baseUrl) 
    .queryParam("name", name) 
    .queryParam("surname", surname) 
    .build().toUriString(); 
Các vấn đề liên quan