Есть ли способ добавить поддержку схемы данных (RF C 2397) в java. net .url? - PullRequest
0 голосов
/ 05 мая 2020

Похоже, что java.net.URL в принципе может быть расширен с помощью пользовательских URLHandler s, и что в настоящее время он не поддерживает data: URL-адреса.

Я работаю со сторонней библиотекой, которая использует URL s, построенные из строк, для извлечения изображений и хочет передавать данные изображения напрямую. Кто-нибудь может порекомендовать существующую реализацию подходящего обработчика?

1 Ответ

1 голос
/ 05 мая 2020

Если вы внимательно прочитаете RF C 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");

Чтобы это работало, вам необходимо создать пакет с именем stackoverflow.data в классе с именем Handler со следующим содержимым:

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());

Я понятия не имею, зачем вам это нужно, но вот и все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...