View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.handler.codec.http;
    17
    18  import java.io.UnsupportedEncodingException;
    19  import java.net.URI;
    20  import java.net.URISyntaxException;
    21  import java.net.URLEncoder;
    22  import java.nio.charset.Charset;
    23  import java.nio.charset.UnsupportedCharsetException;
    24  import java.util.ArrayList;
    25  import java.util.List;
    26
    27  /**
    28   * Creates an URL-encoded URI from a path string and key-value parameter pairs.
    29   * This encoder is for one time use only.  Create a new instance for each URI.
    30   *
    31   * <pre>
    32   * {@link QueryStringEncoder} encoder = new {@link QueryStringEncoder}("/hello");
    33   * encoder.addParam("recipient", "world");
    34   * assert encoder.toString().equals("/hello?recipient=world");
    35   * </pre>
    36   * @see QueryStringDecoder
    37   *
    38   * @apiviz.stereotype utility
    39   * @apiviz.has        org.jboss.netty.handler.codec.http.HttpRequest oneway - - encodes
    40   */
    41  public class QueryStringEncoder {
    42
    43      private final Charset charset;
    44      private final String uri;
    45      private final List<Param> params = new ArrayList<Param>();
    46
    47      /**
    48       * Creates a new encoder that encodes a URI that starts with the specified
    49       * path string.  The encoder will encode the URI in UTF-8.
    50       */
    51      public QueryStringEncoder(String uri) {
    52          this(uri, HttpConstants.DEFAULT_CHARSET);
    53      }
    54
    55      /**
    56       * Creates a new encoder that encodes a URI that starts with the specified
    57       * path string in the specified charset.
    58       */
    59      public QueryStringEncoder(String uri, Charset charset) {
    60          if (uri == null) {
    61              throw new NullPointerException("uri");
    62          }
    63          if (charset == null) {
    64              throw new NullPointerException("charset");
    65          }
    66
    67          this.uri = uri;
    68          this.charset = charset;
    69      }
    70
    71      /**
    72       * @deprecated Use {@link #QueryStringEncoder(String, Charset)} instead.
    73       */
    74      @Deprecated
    75      public QueryStringEncoder(String uri, String charset) {
    76          this(uri, Charset.forName(charset));
    77      }
    78
    79      /**
    80       * Adds a parameter with the specified name and value to this encoder.
    81       */
    82      public void addParam(String name, String value) {
    83          if (name == null) {
    84              throw new NullPointerException("name");
    85          }
    86          if (value == null) {
    87              throw new NullPointerException("value");
    88          }
    89          params.add(new Param(name, value));
    90      }
    91
    92      /**
    93       * Returns the URL-encoded URI object which was created from the path string
    94       * specified in the constructor and the parameters added by
    95       * {@link #addParam(String, String)} method.
    96       */
    97      public URI toUri() throws URISyntaxException {
    98          return new URI(toString());
    99      }
    100
    101     /**
    102      * Returns the URL-encoded URI which was created from the path string
    103      * specified in the constructor and the parameters added by
    104      * {@link #addParam(String, String)} method.
    105      */
    106     @Override
    107     public String toString() {
    108         if (params.isEmpty()) {
    109             return uri;
    110         } else {
    111             StringBuilder sb = new StringBuilder(uri).append("?");
    112             for (int i = 0; i < params.size(); i++) {
    113                 Param param = params.get(i);
    114                 sb.append(encodeComponent(param.name, charset));
    115                 sb.append("=");
    116                 sb.append(encodeComponent(param.value, charset));
    117                 if (i != params.size() - 1) {
    118                     sb.append("&");
    119                 }
    120             }
    121             return sb.toString();
    122         }
    123     }
    124
    125     private static String encodeComponent(String s, Charset charset) {
    126         try {
    127             return URLEncoder.encode(s, charset.name()).replaceAll("\\+", "%20");
    128         } catch (UnsupportedEncodingException e) {
    129             throw new UnsupportedCharsetException(charset.name());
    130         }
    131     }
    132
    133     private static final class Param {
    134
    135         final String name;
    136         final String value;
    137
    138         Param(String name, String value) {
    139             this.value = value;
    140             this.name = name;
    141         }
    142     }
    143 }