fix(wiki): replace broken @JsonCreator with custom StdDeserializer for StageInstructions (#424)

Jackson treated the @JsonCreator factory method as a properties creator
(matching the 'instructions' parameter name to the JSON field), not a
string/delegating creator, so plain-string values still failed at runtime
with "no String-argument constructor/factory method".

Replace with @JsonDeserialize + StdDeserializer that explicitly checks
VALUE_STRING vs START_OBJECT tokens, handling both shorthand strings and
full {instructions, template} objects.
This commit is contained in:
Sharon 2026-06-26 14:33:32 +08:00 committed by GitHub
parent 26dd8a37d5
commit 4e82185be7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,8 +1,14 @@
package vip.mate.wiki.profile;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import lombok.Data;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
@ -43,10 +49,32 @@ public class WikiPageTypeDef {
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(using = WikiPageTypeDef.StageInstructions.Deserializer.class)
public static class StageInstructions {
private String instructions;
/** Optional template key referenced by the create stage. */
private String template;
static class Deserializer extends StdDeserializer<StageInstructions> {
Deserializer() { super(StageInstructions.class); }
@Override
public StageInstructions deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
StageInstructions s = new StageInstructions();
if (p.currentToken() == JsonToken.VALUE_STRING) {
s.setInstructions(p.getText());
} else if (p.currentToken() == JsonToken.START_OBJECT) {
while (p.nextToken() != JsonToken.END_OBJECT) {
String field = p.currentName();
p.nextToken();
if ("instructions".equals(field)) s.setInstructions(p.getValueAsString());
else if ("template".equals(field)) s.setTemplate(p.getText());
else p.skipChildren();
}
}
return s;
}
}
}
@Data