49

私が扱っているコードの多くには、次のような恐ろしいものがあります。

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

さらに悪いことに:

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

次の正しい方法はありますか?

  1. 新しい URL を作成します (または URI です)。
  2. 正しくエスケープされたパラメーターをそれに追加します。
  3. これらのパラメーターに整形式のファイル パスを追加します。
  4. それを文字列に解決します。

本質的に - 文字列を正しく作成するよりも、文字列を作成する方が簡単すぎます。文字列を作成するのと同じくらい簡単で、適切に行う方法はありますか?

追加した

明確にするために-そして少し考えた後-私は次のようなものを探していると思います:

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

ファイルなどに「\」を使用する代わりに、「?」/「&」をエスケープして追加し、「\」を「/」に変更するというすべての不快感に対処するためです。

自分で作成する必要がある場合 (つまり、Apache がオプションでない場合)、さまざまな部分を正しくエスケープするための実際の Java 手法はありますか。パラメータの " " を "." としてエスケープするようなことを意味します。他の場所で " " を "%20" にエスケープします。

4

5 に答える 5

1

私は@Jeroenの提案が好きですが、それは私が望んでいたすべてのことをしたわけではありません.パーツを集めてからaを使用しURIて最終結果を成長させるという彼のアイデアを使用して、私が望むことを行うように見えるこのソリューションをまとめました:

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);
    }
  }

}
于 2013-10-23T12:23:41.627 に答える
-6

おすすめ

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

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

および URL を構築するコード内。

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

    return builder.toString();

}
于 2013-10-23T09:57:18.083 に答える