我正在将我的代码迁移到Java 20。
在这个版本中,java.net.URL#URL(java.lang.String)被弃用了。不幸的是,我有一个类,在旧的URL构造函数中找不到任何替代品。
package com.github.bottomlessarchive.loa.url.service.encoder;
import io.mola.galimatias.GalimatiasParseException;
import org.springframework.stereotype.Service;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Optional;
/**
* This service is responsible for encoding existing {@link URL} instances to valid
* <a href="https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier">resource identifiers</a>.
*/
@Service
public class UrlEncoder {
/**
* Encodes the provided URL to a valid
* <a href="https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier">resource identifier</a> and return
* the new identifier as a URL.
*
* @param link the url to encode
* @return the encoded url
*/
public Optional<URL> encode(final String link) {
try {
final URL url = new URL(link);
// We need to further validate the URL because the java.net.URL's validation is inadequate.
validateUrl(url);
return Optional.of(encodeUrl(url));
} catch (GalimatiasParseException | MalformedURLException | URISyntaxException e) {
return Optional.empty();
}
}
private void validateUrl(final URL url) throws URISyntaxException {
// This will trigger an URISyntaxException. It is needed because the constructor of java.net.URL doesn't always validate the
// passed url correctly.
new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
}
private URL encodeUrl(final URL url) throws GalimatiasParseException, MalformedURLException {
return io.mola.galimatias.URL.parse(url.toString()).toJavaURL();
}
}
幸运的是,我也为这个类编写了测试:
package com.github.bottomlessarchive.loa.url.service.encoder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
class UrlEncoderTest {
private final UrlEncoder underTest = new UrlEncoder();
@ParameterizedTest
@CsvSource(
value = {
"http://www.example.com/?test=Hello world,http://www.example.com/?test=Hello%20world",
"http://www.example.com/?test=ŐÚőúŰÜűü,http://www.example.com/?test=%C5%90%C3%9A%C5%91%C3%BA%C5%B0%C3%9C%C5%B1%C3%BC",
"http://www.example.com/?test=random word £500 bank $,"
+ "http://www.example.com/?test=random%20word%20%C2%A3500%20bank%20$",
"http://www.aquincum.hu/wp-content/uploads/2015/06/Aquincumi-F%C3%BCzetek_14_2008.pdf,"
+ "http://www.aquincum.hu/wp-content/uploads/2015/06/Aquincumi-F%C3%BCzetek_14_2008.pdf",
"http://www.aquincum.hu/wp-content/uploads/2015/06/Aquincumi-F%C3%BCzetek_14 _2008.pdf,"
+ "http://www.aquincum.hu/wp-content/uploads/2015/06/Aquincumi-F%C3%BCzetek_14%20_2008.pdf"
}
)
void testEncodeWhenUsingValidUrls(final String urlToEncode, final String expected) throws MalformedURLException {
final Optional<URL> result = underTest.encode(urlToEncode);
assertThat(result)
.contains(new URL(expected));
}
@ParameterizedTest
@CsvSource(
value = {
"http://промкаталог.рф/PublicDocuments/05-0211-00.pdf"
}
)
void testEncodeWhenUsingInvalidUrls(final String urlToEncode) {
final Optional<URL> result = underTest.encode(urlToEncode);
assertThat(result)
.isEmpty();
}
}
它使用的唯一依赖是galamatias URL库。
有没有人有任何想法,如何在保持功能不变的情况下删除new URL(link)
代码片段?
我尝试了各种方法,比如使用java.net.URI#create
,但它没有产生与以前的解决方案完全相同的结果。例如,包含非编码字符(如http://www.example.com/?test=Hello world
中的空格)的URL会导致IllegalArgumentException。这个问题被URL类解析而没有出错(而我的数据中有很多这样的问题)。而且,像http://промкаталог.рф/PublicDocuments/05-0211-00.pdf
这样无法转换为URL的链接可以通过URI.create成功转换。
new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
- Lakatos Gyula