package io.craft.atom.protocol.http; import static io.craft.atom.protocol.http.HttpConstants.S_AMPERSAND; import static io.craft.atom.protocol.http.HttpConstants.S_EQUAL_SIGN; import io.craft.atom.protocol.AbstractProtocolCodec; import io.craft.atom.protocol.ProtocolEncoder; import io.craft.atom.protocol.ProtocolException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import lombok.ToString; /** * A {@link ProtocolEncoder} which encodes a {@code Map<String, List<String>>} object into bytes * with the <CODE>application/x-www-form-urlencoded</CODE> MIME format follow the HTTP specification, default charset is utf-8. * <br> * Thread safe. * * @author mindwind * @version 1.0, Mar 25, 2013 */ @ToString(callSuper = true) public class HttpParameterEncoder extends AbstractProtocolCodec implements ProtocolEncoder<Map<String, List<String>>> { public HttpParameterEncoder() {} public HttpParameterEncoder(Charset charset) { this.charset = charset; } @Override public byte[] encode(Map<String, List<String>> paras) throws ProtocolException { if (paras == null) return null; StringBuilder buf = new StringBuilder(); Set<Entry<String, List<String>>> entrys = paras.entrySet(); for (Entry<String, List<String>> entry : entrys) { String name = entry.getKey(); List<String> values = entry.getValue(); for (String value : values) { try { name = URLEncoder.encode(name, charset.name()); value = URLEncoder.encode(value, charset.name()); buf.append(name).append(S_EQUAL_SIGN).append(value).append(S_AMPERSAND); } catch (UnsupportedEncodingException e) { throw new ProtocolException(e); } } } // delete last & char buf.deleteCharAt(buf.length() - 1); return buf.toString().getBytes(charset); } }