programing

Jackson은 json에 백슬래시를 추가합니다.

easyjava 2023. 4. 4. 23:20
반응형

Jackson은 json에 백슬래시를 추가합니다.

REST에 Jersey and and를 합니다.JacksonJSON에 관한 정보입니다.절대적인 단순한 가치의 모델, 이것이 가장 전형적인 경우라고 생각합니다.그런데 이상한 결과가 나왔어요.

[{\"name\":\"Nick\",\"role\":\"admin\",\"age\":\"32\",\"rating\":47}]

예상 결과:

[{"name":"Nick","role":"admin","age":"32","rating":47}]

필드의 소스 값에 특수 문자가 포함되어 있지 않습니다.이것은 간단한 단어입니다.

자바 수업도 있고엔티티:

public class User {

  private String name;

  private String role;

  private String age;

  private Integer rating;

휴식 서비스 클래스:

@ServiceConfig(contextName = "myContext")
@Path("/myrest")
public class MyRestService {

  private static final String JSON_CONTENT_TYPE = MediaType.APPLICATION_JSON + ";charset=UTF-8";

  @Context
  protected HttpServletResponse response;

  @GET
  @Path("/users")
  @OpenTransaction
  @Produces({MediaType.APPLICATION_JSON})
  public String findUsers(@QueryParam("department") String department) {

    response.setContentType(JSON_CONTENT_TYPE);
    PDTResponse.status(response).sendStatus(Response.Status.OK.getStatusCode());

    List<User> users = new ArrayList<>();
    users.add(new User("Nick", "admin", "32", 47));

    String jsonInString;
    ObjectMapper mapper = new ObjectMapper();
    try {
        jsonInString = mapper.writeValueAsString(users);
    } catch (JsonProcessingException ex) {
        jsonInString = "thrown exception: " + ex.getMessage();
    }
    return jsonInString;
}

주석을 @JsonRawValue다음 중 하나:

@JsonRawValue
private String name;

그러나 이 경우 결과는 다음과 같습니다.

[{\"name\":Nick,\"role\":admin,\"age\":32,\"rating\":47}]

그리고 나는 예상한다.

[{"name":"Nick","role":"admin","age":"32","rating":47}]

Jackson은 어떤 식으로든 응답의 결과에서 인용구를 벗어난 것이 분명하다.하지만 왜 그렇게 하는 걸까요? 그리고 가장 중요한 것은 어떻게 피할 수 있을까요?그 자체로는 그냥 끈일 뿐이야!따옴표나 특수문자 없이.

용 i i i i를 쓴다.Java 7 ★★★★★★★★★★★★★★★★★」Jackson 2.6.1Postman결과를 테스트합니다.제문 해결 결결 결? ???

Object Mapper는 다음과 같이 설정할 수 있습니다.

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);

자세한 내용은 이쪽

Java의 모든 문자열은 따옴표를 이스케이프해야 합니다.따라서 jsonInString에는 슬래시가 포함되어 있어야 합니다.따옴표가 없어야 하는데 jsonInString을 출력할 때.디버거 같은 걸로 보는 거야?

이렇게 해.

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;
    }
  }

스프링 및 @ControllerAdvice for JSONP를 사용하는 경우 JSON 문자열 래퍼를 만들고 속성에서 @JsonRawValue를 사용합니다.JSONP @ControllerAdvice는 String 응답을 랩하지 않습니다.개체가 필요합니다.

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");
    }
}

객체입니다.{"id":2}
은 " " " " 입니다.callbackparameter({"id":2});

JAX-RS 리소스 클래스를 복잡하게 만드는 것 같습니다.

Jackson을 Jersey 2.x의 JSON 공급자로 사용하기 위해 이러한 인스턴스를 만들 필요가 없습니다.더 좋은 방법이 있어요자세한 내용은 계속 읽어보십시오.

잭슨 모듈 종속성 추가

Jackson 2.x를 JSON 프로바이더로서 사용하려면 , 에 모듈을 추가할 필요가 있습니다.pom.xml 삭제:

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

잭슨 모듈 등록

그런 다음 / 서브클래스에 등록합니다.

@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);
    }
}

/ 서브클래스가 없는 경우,를 에 등록할 수 있습니다.web.xml배포 기술자.특정 리소스, 공급자 및 기능의 완전 수식 클래스 이름은 쉼표로 구분된 초기화 파라미터 값으로 지정할 수 있습니다.

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

Jackson이 제공하는 내용은 입니다.Jackson을 JSON 프로바이더로 사용하는 방법에 대한 자세한 내용은 다음 답변을 참조하십시오.를 커스터마이즈 할 필요가 있는 경우는, 다음의 답변을 참조해 주세요.

리소스 클래스 수정

위에서 설명한 방법을 사용하면 리소스 클래스를 다음과 같이 단순화할 수 있습니다.

@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();
}

이러한 엔드포인트를 요구하면 결과적으로 예상되는 JSON이 제공됩니다.

나도 같은 문제가 있어서 다른 해결책을 시도했지만 잘 되지 않았다.문제는 매퍼가 아니라 매퍼에 대한 입력에 있습니다.고객님의 경우와 마찬가지로:
jsonInString = mapper.writeValueAsString(users);
users는 컬렉션입니다.각 사용자를 다음과 같이 변환해야 합니다.JSONObject, 에 추가합니다.JSONArray다음으로 어레이상의 매퍼를 사용합니다.이렇게 됩니다.
JSONArray users = new JSONArray(); for (Collection user : usersCollection) { JSONObject user = new JSONObject(mapper.writeValueAsString(user)); users.put(user); } mapper.writeValueAsString(user));

이유는 모르겠지만, 제 경우는 다음과 같이 동작합니다.

private static final String COOKIE_TEMPLATE = "{0}={1};Version={2};Domain={3};Max-Age={4};Path='/'";

response.addHeader("Set-Cookie", MessageFormat.format(COOKIE_TEMPLATE, cookie.getName(),cookie.getValue(), cookie.getVersion(), cookie.getDomain(),Integer.toString(cookie.getMaxAge())));
return ResponseEntity.ok(...);

cookie는 javax.servlet.cookie 입니다.Cookie 및 cookie.getValue()에는 에 의해 생성된 문자열이 포함되어 있습니다.

ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);

사용하는 경우

response.addCookie(cookie)

결과 cookie 정의는 백슬래시가 있는 JSON으로 정의되어 있습니다.

근데 만약에 제가

response.addHeader("Set-Cookie",MessageFormat(TEMPLATE,cookie.get...))

JSON과 동일한 쿠키 정의를 관리했지만 백슬래시는 사용하지 않았습니다.

쿠키가 여러 개 있는 경우 addHeader("Set-Cookie")는 원하는 쿠키만 생성/업데이트합니다.다른 것은 유지되고 변경되지 않습니다.

public class StateDate{
    @JsonRawValue
    Boolean state;
    @JsonRawValue
    String date;

    public String toJson() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonWriteFeature.QUOTE_FIELD_NAMES.mappedFeature(), false);
        try {
            return mapper.writeValueAsString(this);
        } catch (com.fasterxml.jackson.core.JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

같은 문제에 직면한 적이 있습니다.다음의 설정을 사용하면, 문제를 해결할 수 있습니다.

final ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, false);

어려움을 겪고도 답이 필요한 일부 사용자용

필드에 @JsonRawValue를 추가합니다.

@JsonRawValue 주석은 Jackson에게 속성을 그대로 직렬화하도록 지시할 수 있습니다.

나조차도 오늘 이 문제를 발견했고 우연히 이 문제를 발견했다.사람들은 백슬래시를 제거하기 위한 여러 가지 방법을 제공했지만 문제는 여기서 우리가 하려는 일의 본질로 귀결된다는 것입니다.

api 호출의 json 응답을 반환하고 싶습니다만,JSONString formatted in way so that it can be printed, read and understood in Java인쇄했을 때, 반품했을 때의 모습 그대로 인쇄됩니다.

간단히 말하면, 함수의 바이트를 반환해야 합니다.String. 반환 유형을 로 변경합니다.byte[]반환:

new ObjectMapper().writeValueAsString(response).getBytes(StandardCharset.UTF_8);

이렇게 하면 읽고 싶은 JSON 중에서 가장 순수한 JSON을 얻을 수 있습니다.대부분의 경우 반대편에서 InputStream을 읽고 있을 때 동일한 클래스에 매핑할 수 없어 작동하지 않을 때 이 문제가 발생합니다.이렇게 하면 고칠 수 있어요.

문제가 되지 않습니다.javascript로 해석하여 사용하면 됩니다.JSON.parse ( response )

언급URL : https://stackoverflow.com/questions/41815818/jackson-adds-backslash-in-json

반응형