有没有一种方法可以将数据方案支持(RFC 2397)添加到java.net.url



看起来java.net.URL原则上可以用自定义URLHandlers进行扩展,而且它目前不支持data:URL。

我正在使用一个第三方库,该库使用由字符串构建的URL来检索图像,并希望直接传递图像数据。是否存在任何人都可以推荐的合适处理程序的现有实现?

如果你仔细阅读RFC 2397,你会发现"数据"URL方案是这样定义的:

data:[<mediatype>][;base64],<data>

因此,要生成这些数据,您需要使用类似的东西:

byte[] fakeImage = new byte[1];
StringBuilder sb = new StringBuilder();
// acquired from file extension
String mimeType = "image/jpg";
sb.append("data:");
sb.append(mimeType);
sb.append(";base64,");
sb.append(Base64.getEncoder().encodeToString(fakeImage));

现在有趣的部分来了:您必须注册自己的协议处理程序,但它是定义良好的:

If this is the first URL object being created with the specifiedprotocol, a stream protocol handler object, an instance ofclass URLStreamHandler, is created for that protocol: 
1.If the application has previously set up an instance of URLStreamHandlerFactory as the stream handler factory,then the createURLStreamHandler method of that instanceis called with the protocol string as an argument to create thestream protocol handler. 
2.If no URLStreamHandlerFactory has yet been set up,or if the factory's createURLStreamHandler methodreturns null, then the constructor finds thevalue of the system property: 
java.protocol.handler.pkgs
If the value of that system property is not null,it is interpreted as a list of packages separated by a verticalslash character '|'. The constructor tries to loadthe class named: 
<package>.<protocol>.Handler
where <package> is replaced by the name of the packageand <protocol> is replaced by the name of the protocol.If this class does not exist, or if the class exists but it is nota subclass of URLStreamHandler, then the next packagein the list is tried. 
3.If the previous step fails to find a protocol handler, then theconstructor tries to load from a system default package. 
<system default package>.<protocol>.Handler
If this class does not exist, or if the class exists but it is not asubclass of URLStreamHandler, then a MalformedURLException is thrown.

所以你只需要写以下内容:

String previousValue = System.getProperty("java.protocol.handler.pkgs") == null ? "" : System.getProperty("java.protocol.handler.pkgs")+"|";
System.setProperty("java.protocol.handler.pkgs", previousValue+"stackoverflow");

为了实现这一点,您必须在名为Handler的类中创建一个名为stackoverflow.data的包,其中包含以下内容:

package stackoverflow.data;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
public class Handler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
}

然后你可以创建一个新的URL而不会出现任何异常:

URL url = new URL(sb.toString());

我不知道你为什么需要这样,但你在那里。

最新更新