Мое приложение должно сохранять и восстанавливать HttpCookie в базе данных. Поэтому я попытался закодировать / декодировать объекты HttpCookie в строку с помощью следующего кода. В некоторых случаях в результате появляется сообщение об ошибке: последний блок не имеет достаточного количества правильных битов.
Да, я прочитал пост об ошибке, но речь идет о чтении через буфер и преобразовании буфера. Это другое, потому что чтение потока происходит за 1 раз !
В некоторых случаях этот код выдает указанное сообщение об ошибке. Как я могу решить это?
public class SerializableHttpCookie implements Serializable {
private static final long serialVersionUID = 6374381323722046732L;
private transient HttpCookie cookie;
private Field fieldHttpOnly; // needed for a workaround
...
public String encode2(HttpCookie cookie) {
this.cookie = cookie;
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(this);
} catch (IOException e) {
logger.error( "IOException in encodeCookie", e);
return null;
}
return Base64.getUrlEncoder().encodeToString( os.toByteArray());
}
public HttpCookie decode2(String encodedCookie) {
byte[] bytes = Base64.getUrlDecoder().decode(encodedCookie);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( bytes);
HttpCookie cookie = null;
try {
ObjectInputStream objectInputStream = new ObjectInputStream( byteArrayInputStream);
cookie = ((SerializableHttpCookie) objectInputStream.readObject()).cookie;
} catch (IOException e) {
logger.error( "IOException in decodeCookie", e);
} catch (ClassNotFoundException e) {
logger.error( "ClassNotFoundException in decodeCookie", e);
}
return cookie;
}
ReadObject и WriteObject:
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(cookie.getName());
out.writeObject(cookie.getValue());
out.writeObject(cookie.getComment());
out.writeObject(cookie.getCommentURL());
out.writeObject(cookie.getDomain());
out.writeLong(cookie.getMaxAge());
out.writeObject(cookie.getPath());
out.writeObject(cookie.getPortlist());
out.writeInt(cookie.getVersion());
out.writeBoolean(cookie.getSecure());
out.writeBoolean(cookie.getDiscard());
out.writeBoolean(getHttpOnly());
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
String name = (String) in.readObject();
String value = (String) in.readObject();
cookie = new HttpCookie(name, value);
cookie.setComment((String) in.readObject());
cookie.setCommentURL((String) in.readObject());
cookie.setDomain((String) in.readObject());
cookie.setMaxAge(in.readLong());
cookie.setPath((String) in.readObject());
cookie.setPortlist((String) in.readObject());
cookie.setVersion(in.readInt());
cookie.setSecure(in.readBoolean());
cookie.setDiscard(in.readBoolean());
setHttpOnly(in.readBoolean());
}
Я использовал разные подходы, такие как следующие, что также приводило к ошибкам (при подсчете). Ошибка помечена как комментарий.
private String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte element : bytes) {
int v = element & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString();
}
private byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
.digit(hexString.charAt(i + 1), 16)); // ERROR: hexString.charAt(i+1) out of range
}
return data;
}
EncodeAndSerialize
Еще один способ сделать это - вызвать код в ответе. Увы, я получаю ту же ошибку при декодировании строки.
new SerializableHttpCookie2().serializeAndEncode(cookie)));
И
HttpCookie cookie = new SerializableHttpCookie2().decodeAndDeserialize(encodedCookie);
Использование библиотеки commons-codec:
public String serializeAndEncode(final HttpCookie cookie) throws IllegalAccessException, IllegalArgumentException {
final String serialized = this.serialize(cookie);
return new String( Hex.encodeHex(serialized.getBytes()));
}
А
public HttpCookie decodeAndDeserialize(final String string)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// final String decoded = this.decode(string);
String decoded;
try {
decoded = new String(Hex.decodeHex(string.toCharArray()));
} catch ( Exception e) {
return null;
}
return this.deserialize(decoded);
}