Skip to content

Commit

Permalink
Merge pull request #3 from alex-cova/teenyJson
Browse files Browse the repository at this point in the history
Teeny json suport
  • Loading branch information
JonathanGiles authored Jul 24, 2024
2 parents 37371b9 + d8c3751 commit 3bfe7d6
Show file tree
Hide file tree
Showing 36 changed files with 3,557 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
pull_request:
types: [ opened, synchronize, reopened ]

env:
AZURE_BLOB_STORAGE_CONNECTION_STRING: ${{ secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING }}

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -25,6 +28,7 @@ jobs:
run: mvn --batch-mode -DskipTests package

- name: Test
timeout-minutes: 5
run: mvn --batch-mode -Dmaven.test.failure.ignore=true test

- name: Report
Expand All @@ -38,6 +42,7 @@ jobs:

- name: Upload to Azure Blob Storage
uses: bacongobbler/[email protected]
if: env.AZURE_BLOB_STORAGE_CONNECTION_STRING != null
with:
source_dir: 'target/apidocs'
container_name: '$web'
Expand Down
14 changes: 13 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,19 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>test</scope>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.37</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.37</version>
<scope>test</scope>
</dependency>
</dependencies>

Expand Down
69 changes: 68 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public ServerSentEventHandler chatMessages() {
Use it directly anywhere:

```java
Post("/message")
@Post("/message")
public void message(@QueryParam("message") String message,
@EventHandler("messages") ServerSentEventHandler chatMessagesEventHandler) {
chatMessagesEventHandler.sendMessage(message);
Expand Down Expand Up @@ -348,6 +348,73 @@ public GsonMessageConverter getGsonConverter() {
}
```

## TeenyJson

TeenyHttpd includes a simple JSON library called TeenyJson. It is a simple, lightweight JSON library that is used to convert JSON strings to Java objects, and vice versa.
It is not as feature-rich as other JSON libraries, but it is lightweight and easy to use.

### Parsing JSON

```java
Person person = new TeenyJson().readValue(json, Person.class);
```

Similar to jackson to parse a ambiguous property, you can use the `@JsonDeserialize` annotation:

```java
@JsonDeserialize(contentAs = ObjectC.class)
public void setList(List<? extends ObjectC> list) {
this.list = list;
}

@JsonDeserialize(as = ObjectC.class)
public void setC(ObjectC c) {
this.c = c;
}
```

### Generating JSON

```java
Person person = new Person("John", 30, null);
String json = new TeenyJson().writeValueAsString(person);
```

To give a property an alias in the JSON, you can use the `@JsonProperty` annotation:

```java
@JsonAlias("bestSongs")
public Set<String> getFavoriteSongs() {
return favoriteSongs;
}
```

To ignore a property in the JSON, you can use the `@JsonIgnore` annotation:

```java
@JsonIgnore
public String getSecret() {
return secret;
}
```

To ignore all properties that are null, you can use the `@JsonIncludeNonNull` annotation:

```java
@JsonIncludeNonNull
public class Person {
// ...
}
```

You can also customize the deserialization and serialization process by specifying a custom serializer or deserializer:

```java
new TeenyJson()
.registerSerializer(String.class, String::toUpperCase)
.registerParser(String.class, (value) -> value.toString().toLowerCase());
```

## Project Management

Releases are performed using `mvn clean deploy -Prelease`.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ private TeenyApplication() {
server = new TeenyHttpd(Integer.parseInt(System.getProperty("server.port", "8080")));
this.messageConverterMap = new HashMap<>();
this.messageConverterMap.put(DefaultMessageConverter.INSTANCE.getContentType(), DefaultMessageConverter.INSTANCE);
this.messageConverterMap.put("application/json", new net.jonathangiles.tools.teenyhttpd.json.TeenyJsonMessageConverter());
}

public TeenyApplication registerMessageConverter(MessageConverter messageConverter) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package net.jonathangiles.tools.teenyhttpd.implementation;

import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.Arrays;
import java.util.Objects;

/** A helper class to hold the type arguments of a parameterized type and provide some utility methods. */
public final class ParameterizedTypeHelper implements Type {
private final Class<?> firstType;
private final Class<?> parentType;//nullable
private final Type[] typeArguments;

public ParameterizedTypeHelper(Class<?> firstType, Class<?> parentType) {
this.firstType = firstType;
this.parentType = parentType;
this.typeArguments = null;
}

ParameterizedTypeHelper(Class<?> parentType, Type[] arguments) {
this.firstType = getRealClass(arguments[0]);
this.parentType = parentType;
this.typeArguments = arguments;
}

/**
* Returns the real class of the given type.
*
* @param type the type to get the real class of
* @return the real class of the given type
*/
private Class<?> getRealClass(Type type) {
if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
return (Class<?>) wildcardType.getUpperBounds()[0];
}

return (Class<?>) type;
}

/**
* Returns a new instance of ParameterizedTypeHelper with the given first type.
*
* @param firstType the first type
* @return a new instance of ParameterizedTypeHelper
*/
public ParameterizedTypeHelper withFirstType(Class<?> firstType) {
if (typeArguments == null) {
return new ParameterizedTypeHelper(firstType, parentType);
}

Type[] args = new Type[typeArguments.length];

args[0] = firstType;
System.arraycopy(typeArguments, 1, args, 1, typeArguments.length - 1);

return new ParameterizedTypeHelper(parentType, args);
}

@Override
public String getTypeName() {
return getClass().getSimpleName();
}

public boolean isParentTypeOf(Class<?> type) {
return parentType != null && type.isAssignableFrom(parentType);
}

public Type[] getTypeArguments() {
return typeArguments;
}

public Class<?> getFirstType() {
return firstType;
}

/**
* @return the second type of the parameterized type
* @throws NullPointerException if the type is not a ParameterizedType
*/
public Class<?> getSecondType() {
Objects.requireNonNull(typeArguments, "Type is not a ParameterizedType");
return getRealClass(typeArguments[1]);
}

public Class<?> getParentType() {
return parentType;
}

@Override
public String toString() {
return "ParameterizedTypeHelper{" +
"firstType=" + firstType +
", parentType=" + parentType +
", typeArguments=" + Arrays.toString(typeArguments) +
'}';
}
}
Loading

0 comments on commit 3bfe7d6

Please sign in to comment.