The Wayback Machine - http://web.archive.org/web/20201201210245/https://github.com/vert-x3/vertx-web/issues/1146
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CaseInsensitiveHeaders.class is not serializable, provide a default Jackson stdSerializer and stdDeserializer for optional use #1146

Open
StephenOTT opened this issue Jan 24, 2019 · 13 comments

Comments

@StephenOTT
Copy link

@StephenOTT StephenOTT commented Jan 24, 2019

The CaseInsensitiveHeaders.class does not support serialization. This is a problem when you want to do things like passing common headers into verticles through config(). (JsonObject).

Would be great if a jackson stdSerializer and stdDeserilizer were provided to optionally support this.

here is my implementation that can be reused by others, and hopefully can be added in the web client in the future

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.vertx.core.MultiMap;
import io.vertx.core.http.CaseInsensitiveHeaders;

import java.io.IOException;


public class CaseInsensitiveHeadersDeserializer extends StdDeserializer<MultiMap> {

    protected CaseInsensitiveHeadersDeserializer() {
        super(MultiMap.class);
    }

    @Override
    public MultiMap deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        CaseInsensitiveHeaders headers = new CaseInsensitiveHeaders();
        TreeNode tree = p.readValueAsTree();
        if (tree.isArray()){
            ArrayNode array = (ArrayNode)tree;
            array.forEach(item->{
                item.fields().forEachRemaining(f->{
                    headers.add(f.getKey(), f.getValue().asText());
                });
            });
        }
        return headers;
    }

}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import io.vertx.core.MultiMap;

import java.io.IOException;


public class CaseInsensitiveHeadersSerializer extends StdSerializer<MultiMap> {

    protected CaseInsensitiveHeadersSerializer() {
        super(MultiMap.class);
    }

    @Override
    public void serialize(MultiMap value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartArray();
        value.forEach(v -> {
            try {
                gen.writeObject(v);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        gen.writeEndArray();
    }
}

and in a class somewhere when you need to capture these you can do:

...
    @JsonSerialize(using = CaseInsensitiveHeadersSerializer.class)
    @JsonDeserialize(using = CaseInsensitiveHeadersDeserializer.class)
    private MultiMap commonHeaders = new CaseInsensitiveHeaders();
...

In your Verticle you can do

SomeClassHoldingMyheaders externalTaskOptions = Json.decodeValue(config().getString("headers"), SomeClassHoldingMyheaders.class)

and in your verticle that deploys the verticle using the config you can do

JsonObject configObject = new JsonObject();
configObject.put("headers", Json.encode(myHeaders));

Where myHeaders is your SomeClassHoldingMyheaders.class instance

@pmlopes
Copy link
Member

@pmlopes pmlopes commented Feb 13, 2019

However this should be against core as JSON serializers are defined there.

@StephenOTT
Copy link
Author

@StephenOTT StephenOTT commented Apr 9, 2019

Are you saying where this code would go?

@vietj
Copy link
Contributor

@vietj vietj commented Apr 9, 2019

why is this necessary ?

@vietj
Copy link
Contributor

@vietj vietj commented Apr 9, 2019

for web session ?

@StephenOTT
Copy link
Author

@StephenOTT StephenOTT commented Apr 9, 2019

Which part? The reason for sending the headers is defined in original issue text. The ability to send headers into verticle config or through event bus. In the default setup it cannot be serialized into json as per the issue outlined.

@vietj
Copy link
Contributor

@vietj vietj commented Apr 9, 2019

ok, I think then it would be better to be java serializable than Jackson serializable, as we want to decouple from jackson

@StephenOTT
Copy link
Author

@StephenOTT StephenOTT commented Apr 10, 2019

If you are decoupling from Jackson, are you transitioning to using serializable as the default data format for the bus and config? Any blog or write up on this decoupling?

@vietj
Copy link
Contributor

@vietj vietj commented Apr 10, 2019

it is for vert.x 4, actually the event bus has its own serialisation mechanism which is used for Buffer, we could have an event bus serializer for MultiMap as well

@vietj
Copy link
Contributor

@vietj vietj commented Apr 10, 2019

that being said Jackson will still be used in Vert.x 4, but we don't want to expose Jackson APIs or make it mandatory.

@slinkydeveloper
Copy link
Member

@slinkydeveloper slinkydeveloper commented Apr 15, 2019

In Vert.x 4 we can create a codec for MultiMap and provide an implementation like this https://github.com/vert-x3/vertx-web/blob/master/vertx-web-api-contract/src/main/java/io/vertx/ext/web/api/OperationResponse.java#L32

@vietj
Copy link
Contributor

@vietj vietj commented Apr 16, 2019

EventBus uses Java serialization and not json, so why this discussion relates to JSON ?

@slinkydeveloper
Copy link
Member

@slinkydeveloper slinkydeveloper commented Apr 16, 2019

The problem is encoding/decoding to JSON object to add it to JSON configs or send through the event bus. JSON encode/decode seems a more general solution for this problem

@vietj
Copy link
Contributor

@vietj vietj commented Apr 16, 2019

sure @slinkydeveloper that being said I don't want to turn every object in Vert.x into json encoding/decoding (at least in the vertx project)

In addition this issue mentions issues with the Event Bus serialisation, not general JSON serialisation as far as I could read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

4 participants
You can’t perform that action at this time.