Refactor thumbnail URI handling to support width parameter and improve error messaging

John Niang 2025-09-30 15:31:23 +08:00
parent c4bd70f832
commit 398a818935
No known key found for this signature in database
GPG Key ID: D7363C015BBCAA59
3 changed files with 11 additions and 56 deletions

View File

@ -1,20 +1,16 @@
package run.halo.app.core.endpoint.theme;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.fn.builders.operation.Builder;
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
@ -66,10 +62,6 @@ public class ThumbnailEndpoint implements CustomEndpoint {
.build();
}
public ThumbnailService getThumbnailService() {
return thumbnailService;
}
private Mono<ServerResponse> getThumbnailByUri(ServerRequest request) {
var uri = request.queryParam("uri")
.filter(StringUtils::isNotBlank)
@ -81,11 +73,15 @@ public class ThumbnailEndpoint implements CustomEndpoint {
}
var size = request.queryParam("size")
.filter(StringUtils::isNotBlank)
.flatMap(ThumbnailSize::optionalValueOf);
if (size.isEmpty()) {
return Mono.error(
new ServerWebInputException("Required parameter 'size' is missing or invalid")
.flatMap(ThumbnailSize::optionalValueOf)
.or(() -> request.queryParam("width")
.filter(StringUtils::isNotBlank)
.map(ThumbnailSize::fromWidth)
);
if (size.isEmpty()) {
return Mono.error(new ServerWebInputException(
"Required parameter 'size' or 'width' is missing or invalid"
));
}
return thumbnailService.get(uri.get(), size.get())
.defaultIfEmpty(uri.get())
@ -95,49 +91,6 @@ public class ThumbnailEndpoint implements CustomEndpoint {
);
}
static class ThumbnailQuery {
private final MultiValueMap<String, String> params;
public ThumbnailQuery(MultiValueMap<String, String> params) {
this.params = params;
}
@Schema(requiredMode = REQUIRED)
public URI getUri() {
var uriStr = params.getFirst("uri");
if (StringUtils.isBlank(uriStr)) {
throw new ServerWebInputException("Required parameter 'uri' is missing");
}
try {
return URI.create(uriStr);
} catch (IllegalArgumentException e) {
throw new ServerWebInputException("Invalid URI: " + uriStr);
}
}
@Schema(requiredMode = REQUIRED)
public ThumbnailSize getSize() {
var size = params.getFirst("size");
if (StringUtils.isBlank(size)) {
throw new ServerWebInputException("Required parameter 'size' is missing");
}
return ThumbnailSize.fromName(size);
}
public static void buildParameters(Builder builder) {
builder.parameter(parameterBuilder()
.in(ParameterIn.QUERY)
.name("uri")
.description("The URI of the image")
.required(true))
.parameter(parameterBuilder()
.in(ParameterIn.QUERY)
.name("size")
.description("The size of the thumbnail,available values are s,m,l,xl")
.required(true));
}
}
@Override
public GroupVersion groupVersion() {
return new GroupVersion("api.storage.halo.run", "v1alpha1");

View File

@ -13,6 +13,7 @@ public interface ThumbnailFinder {
/**
* Generate thumbnail uri from given image uri and size.
*
* @param uri URI of the original image, must be encoded
* @param size the size of thumbnail to generate
* @return the generated thumbnail url
*/

View File

@ -21,7 +21,8 @@ public class ThumbnailFinderImpl implements ThumbnailFinder {
return Mono.fromCallable(() -> URI.create(uriStr))
.flatMap(uri -> thumbnailService.get(uri, ThumbnailSize.fromName(size)))
.map(URI::toASCIIString)
.onErrorReturn(IllegalArgumentException.class, uriStr);
.onErrorComplete(IllegalArgumentException.class)
.defaultIfEmpty(uriStr);
}
}