-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ca433ff
commit b6bda8c
Showing
9 changed files
with
382 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/main/java/com/unitvectory/jsonschema4springboot/JsonSchemaCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package com.unitvectory.jsonschema4springboot; | ||
|
||
import com.networknt.schema.JsonSchema; | ||
|
||
/** | ||
* JSON Schema Cache interface. | ||
* | ||
* @author Jared Hatfield (UnitVectorY Labs) | ||
*/ | ||
public interface JsonSchemaCache { | ||
|
||
/** | ||
* Get a cached schema. | ||
* | ||
* @param path the path | ||
* @return the JsonSchema; null if not found | ||
*/ | ||
JsonSchema getSchema(String path); | ||
|
||
/** | ||
* Cache a JsonSchema | ||
* | ||
* @param path the path | ||
* @param schema the JsonSchema | ||
*/ | ||
void cacheSchema(String path, JsonSchema schema); | ||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/unitvectory/jsonschema4springboot/JsonSchemaCacheDefault.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package com.unitvectory.jsonschema4springboot; | ||
|
||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import com.networknt.schema.JsonSchema; | ||
|
||
/** | ||
* The Default JSON Schema Cache implementation. | ||
* | ||
* Caches an unbounded number of schemas perpetually. | ||
* | ||
* @author Jared Hatfield (UnitVectorY Labs) | ||
*/ | ||
class JsonSchemaCacheDefault implements JsonSchemaCache { | ||
|
||
private Map<String, JsonSchema> cache = new ConcurrentHashMap<>(); | ||
|
||
@Override | ||
public JsonSchema getSchema(String path) { | ||
return this.cache.get(path); | ||
} | ||
|
||
@Override | ||
public void cacheSchema(String path, JsonSchema schema) { | ||
this.cache.put(path, schema); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/unitvectory/jsonschema4springboot/JsonSchemaLookup.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package com.unitvectory.jsonschema4springboot; | ||
|
||
import com.networknt.schema.JsonSchema; | ||
import com.networknt.schema.SpecVersion.VersionFlag; | ||
|
||
/** | ||
* JSON Schema lookup interface. | ||
* | ||
* @author Jared Hatfield (UnitVectorY Labs) | ||
*/ | ||
public interface JsonSchemaLookup { | ||
|
||
/** | ||
* Get a cached schema. | ||
* | ||
* @param version the JSON Schema version | ||
* @param path the path | ||
* @return the JsonSchema; null if not found | ||
* @throws ValidateJsonSchemaException schema was unable to be loaded | ||
*/ | ||
JsonSchema getSchema(VersionFlag version, String path) throws ValidateJsonSchemaException; | ||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/com/unitvectory/jsonschema4springboot/JsonSchemaLookupDefault.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package com.unitvectory.jsonschema4springboot; | ||
|
||
import java.io.InputStream; | ||
import org.springframework.core.io.ClassPathResource; | ||
import org.springframework.core.io.Resource; | ||
import com.networknt.schema.JsonSchema; | ||
import com.networknt.schema.JsonSchemaFactory; | ||
import com.networknt.schema.SpecVersion.VersionFlag; | ||
|
||
/** | ||
* JSON Schema lookup interface. | ||
* | ||
* This loads schemas from the class path by default. | ||
* | ||
* @author Jared Hatfield (UnitVectorY Labs) | ||
*/ | ||
public class JsonSchemaLookupDefault implements JsonSchemaLookup { | ||
|
||
@Override | ||
public JsonSchema getSchema(VersionFlag version, String path) | ||
throws ValidateJsonSchemaException { | ||
// Get the factory for the specified version | ||
JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(version); | ||
|
||
// Load the resource from the class path | ||
Resource resource = new ClassPathResource(path); | ||
if (!resource.exists()) { | ||
throw new ValidateJsonSchemaException("JSON Schema not found at path: " + path); | ||
} | ||
|
||
// Load the schema | ||
try (InputStream schemaStream = resource.getInputStream()) { | ||
return schemaFactory.getSchema(schemaStream); | ||
} catch (Exception e) { | ||
throw new ValidateJsonSchemaException("JSON Schema failed to load from path: " + path, | ||
e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
src/main/java/com/unitvectory/jsonschema4springboot/ValidateJsonSchemaArgumentResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package com.unitvectory.jsonschema4springboot; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.Set; | ||
import javax.servlet.http.HttpServletRequest; | ||
import org.springframework.core.MethodParameter; | ||
import org.springframework.util.StreamUtils; | ||
import org.springframework.web.bind.support.WebDataBinderFactory; | ||
import org.springframework.web.context.request.NativeWebRequest; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.method.support.ModelAndViewContainer; | ||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.networknt.schema.JsonSchema; | ||
import com.networknt.schema.ValidationMessage; | ||
import lombok.AllArgsConstructor; | ||
|
||
/** | ||
* The argument resolver that supports JSON Schema validation. | ||
* | ||
* @author Jared Hatfield (UnitVectorY Labs) | ||
*/ | ||
@AllArgsConstructor | ||
public class ValidateJsonSchemaArgumentResolver implements HandlerMethodArgumentResolver { | ||
|
||
/** | ||
* The configuration | ||
*/ | ||
private final ValidateJsonSchemaConfig config; | ||
|
||
@Override | ||
public final boolean supportsParameter(MethodParameter parameter) { | ||
// Only applies to ValidateJsonSchema annotation | ||
return parameter.hasParameterAnnotation(ValidateJsonSchema.class); | ||
} | ||
|
||
@Override | ||
public final Object resolveArgument(MethodParameter parameter, | ||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest, | ||
WebDataBinderFactory binderFactory) throws Exception { | ||
// Get the annotation | ||
String schemaPath = parameter.getParameterAnnotation(ValidateJsonSchema.class).schemaPath(); | ||
|
||
// First try the cache | ||
JsonSchema schema = this.config.getCache().getSchema(schemaPath); | ||
if (schema == null) { | ||
schema = this.config.getLookup().getSchema(this.config.getSpecVersion(), schemaPath); | ||
|
||
// Failed to get the | ||
if (schema == null) { | ||
throw new ValidateJsonSchemaException("Failed to load JSON Schema"); | ||
} | ||
|
||
// Cache the value | ||
this.config.getCache().cacheSchema(schemaPath, schema); | ||
} | ||
|
||
// Get the JSON as a String | ||
HttpServletRequest httpServletRequest = | ||
webRequest.getNativeRequest(HttpServletRequest.class); | ||
String jsonString = StreamUtils.copyToString(httpServletRequest.getInputStream(), | ||
StandardCharsets.UTF_8); | ||
|
||
// Parse into a JsonNode, needed for validation | ||
JsonNode json = this.config.getObjectMapper().readTree(jsonString); | ||
|
||
// Validate the Json | ||
Set<ValidationMessage> validationResult = schema.validate(json); | ||
if (validationResult.isEmpty()) { | ||
// Convert the JSON into the object | ||
return this.config.getObjectMapper().treeToValue(json, parameter.getParameterType()); | ||
} else { | ||
// Throw the validation exception | ||
throw new ValidateJsonSchemaException(validationResult); | ||
} | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
src/main/java/com/unitvectory/jsonschema4springboot/ValidateJsonSchemaConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package com.unitvectory.jsonschema4springboot; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.networknt.schema.SpecVersion; | ||
import lombok.Builder; | ||
import lombok.Value; | ||
|
||
/** | ||
* The validate JSON Schema configuration. | ||
* | ||
* @author Jared Hatfield (UnitVectorY Labs) | ||
*/ | ||
@Value | ||
@Builder | ||
public class ValidateJsonSchemaConfig { | ||
|
||
@Builder.Default | ||
private final ObjectMapper objectMapper = new ObjectMapper(); | ||
|
||
@Builder.Default | ||
private final SpecVersion.VersionFlag specVersion = SpecVersion.VersionFlag.V7; | ||
|
||
@Builder.Default | ||
private final JsonSchemaCache cache = new JsonSchemaCacheDefault(); | ||
|
||
@Builder.Default | ||
private final JsonSchemaLookup lookup = new JsonSchemaLookupDefault(); | ||
} |
Oops, something went wrong.