18
18
19
19
import java .nio .charset .Charset ;
20
20
import java .util .Base64 ;
21
+ import javax .xml .bind .DatatypeConverter ;
21
22
22
23
import org .springframework .lang .UsesJava8 ;
23
24
24
25
/**
25
26
* A simple utility class for Base64 encoding and decoding.
26
27
*
27
- * <p>Adapts to either Java 8's {@link java.util.Base64} class or Apache
28
- * Commons Codec's {@link org.apache.commons.codec.binary.Base64} class.
29
- * With neither Java 8 nor Commons Codec present, encode/decode calls
30
- * will fail with an IllegalStateException.
28
+ * <p>Adapts to either Java 8's {@link java.util.Base64} class or Apache Commons Codec's
29
+ * {@link org.apache.commons.codec.binary.Base64} class. With neither Java 8 nor Commons
30
+ * Codec present, {@link #encode}/{@link #decode} calls will throw an IllegalStateException.
31
+ * However, as of Spring 4.2, {@link #encodeToString} and {@link #decodeFromString} will
32
+ * nevertheless work since they can delegate to the JAXB DatatypeConverter as a fallback.
31
33
*
32
34
* @author Juergen Hoeller
33
35
* @since 4.1
34
36
* @see java.util.Base64
35
37
* @see org.apache.commons.codec.binary.Base64
38
+ * @see javax.xml.bind.DatatypeConverter#printBase64Binary
39
+ * @see javax.xml.bind.DatatypeConverter#parseBase64Binary
36
40
*/
37
41
public abstract class Base64Utils {
38
42
@@ -55,73 +59,84 @@ else if (ClassUtils.isPresent("org.apache.commons.codec.binary.Base64", Base64Ut
55
59
}
56
60
57
61
/**
58
- * Assert that Byte64 encoding is actually supported.
62
+ * Assert that Byte64 encoding between byte arrays is actually supported.
59
63
* @throws IllegalStateException if neither Java 8 nor Apache Commons Codec is present
60
64
*/
61
- private static void assertSupported () {
62
- Assert .state (delegate != null , "Neither Java 8 nor Apache Commons Codec found - Base64 encoding not supported" );
65
+ private static void assertDelegateAvailable () {
66
+ Assert .state (delegate != null ,
67
+ "Neither Java 8 nor Apache Commons Codec found - Base64 encoding between byte arrays not supported" );
63
68
}
64
69
65
70
66
71
/**
67
72
* Base64-encode the given byte array.
68
73
* @param src the original byte array (may be {@code null})
69
74
* @return the encoded byte array (or {@code null} if the input was {@code null})
70
- * @throws IllegalStateException if Base64 encoding is not supported,
71
- * i.e. neither Java 8 nor Apache Commons Codec is present at runtime
75
+ * @throws IllegalStateException if Base64 encoding between byte arrays is not
76
+ * supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
72
77
*/
73
78
public static byte [] encode (byte [] src ) {
74
- assertSupported ();
79
+ assertDelegateAvailable ();
75
80
return delegate .encode (src );
76
81
}
77
82
83
+ /**
84
+ * Base64-decode the given byte array.
85
+ * @param src the encoded byte array (may be {@code null})
86
+ * @return the original byte array (or {@code null} if the input was {@code null})
87
+ * @throws IllegalStateException if Base64 encoding between byte arrays is not
88
+ * supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
89
+ */
90
+ public static byte [] decode (byte [] src ) {
91
+ assertDelegateAvailable ();
92
+ return delegate .decode (src );
93
+ }
94
+
78
95
/**
79
96
* Base64-encode the given byte array to a String.
80
97
* @param src the original byte array (may be {@code null})
81
98
* @return the encoded byte array as a UTF-8 String
82
99
* (or {@code null} if the input was {@code null})
83
- * @throws IllegalStateException if Base64 encoding is not supported,
84
- * i.e. neither Java 8 nor Apache Commons Codec is present at runtime
85
100
*/
86
101
public static String encodeToString (byte [] src ) {
87
- assertSupported ();
88
102
if (src == null ) {
89
103
return null ;
90
104
}
91
105
if (src .length == 0 ) {
92
106
return "" ;
93
107
}
94
- return new String (delegate .encode (src ), DEFAULT_CHARSET );
95
- }
96
108
97
- /**
98
- * Base64-decode the given byte array.
99
- * @param src the encoded byte array (may be {@code null})
100
- * @return the original byte array (or {@code null} if the input was {@code null})
101
- * @throws IllegalStateException if Base64 encoding is not supported,
102
- * i.e. neither Java 8 nor Apache Commons Codec is present at runtime
103
- */
104
- public static byte [] decode (byte [] src ) {
105
- assertSupported ();
106
- return delegate .decode (src );
109
+ if (delegate != null ) {
110
+ // Full encoder available
111
+ return new String (delegate .encode (src ), DEFAULT_CHARSET );
112
+ }
113
+ else {
114
+ // JAXB fallback for String case
115
+ return DatatypeConverter .printBase64Binary (src );
116
+ }
107
117
}
108
118
109
119
/**
110
120
* Base64-decode the given byte array from an UTF-8 String.
111
121
* @param src the encoded UTF-8 String (may be {@code null})
112
122
* @return the original byte array (or {@code null} if the input was {@code null})
113
- * @throws IllegalStateException if Base64 encoding is not supported,
114
- * i.e. neither Java 8 nor Apache Commons Codec is present at runtime
115
123
*/
116
124
public static byte [] decodeFromString (String src ) {
117
- assertSupported ();
118
125
if (src == null ) {
119
126
return null ;
120
127
}
121
128
if (src .length () == 0 ) {
122
129
return new byte [0 ];
123
130
}
124
- return delegate .decode (src .getBytes (DEFAULT_CHARSET ));
131
+
132
+ if (delegate != null ) {
133
+ // Full encoder available
134
+ return delegate .decode (src .getBytes (DEFAULT_CHARSET ));
135
+ }
136
+ else {
137
+ // JAXB fallback for String case
138
+ return DatatypeConverter .parseBase64Binary (src );
139
+ }
125
140
}
126
141
127
142
0 commit comments