Jackson adds backslash in json

后端 未结 8 895
伪装坚强ぢ
伪装坚强ぢ 2020-12-31 00:55

I\'m building REST service on Jersey and using Jackson to produce JSON from java classes of my model. Model with absolutely simple values, I think

相关标签:
8条回答
  • 2020-12-31 01:21

    If you are using Spring and the @ControllerAdvice for JSONP, then create a wrapper for the JSON string and use @JsonRawValue on the property. The JSONP @ControllerAdvice will not wrap a String response, it needs an Object.

    public class JsonStringResponse {    
        @JsonValue
        @JsonRawValue
        private String value;
    
        public JsonStringResponse(String value) {
            this.value = value;
        }
    }  
    
    @GetMapping
    public ResponseEntity<JsonStringResponse> getJson() {
        String json = "{"id":2}";
        return ResponseEntity.ok().body(new JsonStringResponse(json));
    }
    
    
    @ControllerAdvice
    public class JsonpControllerAdvice extends AbstractJsonpResponseBodyAdvice {
        public JsonpControllerAdvice() {
            super("callback");
        }
    }
    

    Response is a json object {"id":2}
    If there is a callback parameter the response is callbackparameter({"id":2});

    0 讨论(0)
  • 2020-12-31 01:23

    Do this.

    ObjectMapper mapper = new ObjectMapper();
    mapper.getFactory().setCharacterEscapes(new JsonUtil().new CustomCharacterEscapes());
    ObjectWriter writer = mapper.writer();
    
    String jsonDataObject = mapper.writeValueAsString(configMap);       
    
    public class CustomCharacterEscapes extends CharacterEscapes {
    
    private final int[] _asciiEscapes;
    
        public CustomCharacterEscapes() {
           _asciiEscapes = standardAsciiEscapesForJSON();
           //By default the ascii Escape table in jackson has " added as escape string
           //overwriting that here.
           _asciiEscapes['"'] = CharacterEscapes.ESCAPE_NONE;
         }
    
         @Override
         public int[] getEscapeCodesForAscii() {
           return _asciiEscapes;
         }
    
         @Override
         public SerializableString getEscapeSequence(int i) {
           return null;
        }
      }
    
    0 讨论(0)
  • 2020-12-31 01:23

    It should not be a problem, just you need to parse it in javascript and use it : JSON.parse(response)

    0 讨论(0)
  • 2020-12-31 01:26

    You can configure the ObjectMapper:

    final ObjectMapper mapper = new ObjectMapper();
    mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
    mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    String jsonUsers = mapper.writeValueAsString(users);
    

    more info here

    0 讨论(0)
  • 2020-12-31 01:30

    I have also the same problem and tried different solutions, but non works. The problem is not with the mapper, but with the input to the mapper. As in your case:
    jsonInString = mapper.writeValueAsString(users);
    'users' is a collection. You need to convert each user to JSONObject, add it to JSONArray and then use the mapper on the array: like this
    JSONArray users = new JSONArray(); for (Collection user : usersCollection) { JSONObject user = new JSONObject(mapper.writeValueAsString(user)); users.put(user); } mapper.writeValueAsString(user));

    0 讨论(0)
  • 2020-12-31 01:31

    Looks like you are over complicating your JAX-RS resource class.

    To use Jackson as a JSON provider for Jersey 2.x, you don't need to create an ObjectMapper instance like that. There's a better way to achieve it. Keep reading for more details.

    Adding Jackson module dependencies

    To use Jackson 2.x as your JSON provider you need to add jersey-media-json-jackson module to your pom.xml file:

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.25.1</version>
    </dependency>
    

    Registering the Jackson module

    Then register the JacksonFeature in your Application / ResourceConfig subclass:

    @ApplicationPath("/api")
    public class MyApplication extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(JacksonFeature.class);
            return classes;
        }
    }
    
    @ApplicationPath("/api")
    public class MyApplication extends ResourceConfig {
    
        public MyApplication() {
            register(JacksonFeature.class);
        }
    }
    

    If you don't have an Application / ResourceConfig subclass, you can register the JacksonFeature in your web.xml deployment descriptor. The specific resource, provider and feature fully-qualified class names can be provided in a comma-separated value of jersey.config.server.provider.classnames initialization parameter.

    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>org.glassfish.jersey.jackson.JacksonFeature</param-value>
    </init-param>
    

    The MessageBodyWriter provided by Jackson is JacksonJsonProvider. For more details on how to use Jackson as a JSON provider, have a look at this answer. If you need to customize the ObjectMapper, refer to this answer.

    Fixing your resource class

    By using the approach described above, you resource class can be as simple as:

    @Path("/users")
    public class MyRestService {
    
      @GET
      @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8"})
      public List<User> findUsers() {
    
        List<User> users = new ArrayList<>();
        users.add(new User("Nick", "admin", "32", 47));
    
        return Response.ok(users).build();
    }
    

    When requesting such endpoint, it will give you the expected JSON as result.

    0 讨论(0)
提交回复
热议问题