2

Java 6、Tomcat 7、Jersey 1.15、Jackson 2.0.6 (FasterXml maven repo から)、および www.json.org パーサーを使用して、JSON 文字列をきれいに印刷しようとしているので、curl -X GET コマンドでインデントされているように見えますライン。

次のアーキテクチャを持つ単純な Web サービスを作成しました。

私の POJO (モデル クラス):

Family.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Family {
    private String father;
    private String mother;

    private List<Children> children;

    // Getter & Setters
}

Children.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Children {
    private String name;
    private String age;
    private String gender;

    // Getters & Setters
}

ユーティリティ クラスを使用して、次のように POJO をハード コードすることにしました。

public class FamilyUtil {

    public static Family getFamily() {
        Family family = new Family();
        family.setFather("Joe");
        family.setMother("Jennifer");

        Children child = new Children();
        child.setName("Jimmy");
        child.setAge("12");
        child.setGender("male");
        List<Children> children = new ArrayList<Children>();

        children.add(child);

        family.setChildren(children);
        return family;
    }
}

私のウェブサービス:

import java.io.IOException;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jettison.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.myapp.controller.myappController;
import com.myapp.resource.output.HostingSegmentOutput;
import com.myapp.util.FamilyUtil;

@Path("")
public class MyWebService {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public static String getFamily() throws IOException, 
                                            JsonGenerationException, 
                                            JsonMappingException, 
                                            JSONException, 
                                            org.json.JSONException {
        ObjectMapper mapper = new ObjectMapper(); 
        String uglyJsonString = mapper.writeValueAsString(FamilyUtil.getFamily());
        System.out.println(uglyJsonString);
        JSONTokener tokener = new JSONTokener(uglyJsonString);
        JSONObject finalResult = new JSONObject(tokener);
        return finalResult.toString(4);         
    }
}

これを使用して実行すると:

curl -X GET http://localhost:8080/mywebservice

私はEclipseのコンソールでこれを取得します:

{"father":"Joe","mother":"Jennifer","children":[{"name":"Jimmy","age":"12","gender":"male"}]}

ただし、コマンド ラインの curl コマンドから (この応答はより重要です):

"{\n    \"mother\": \"Jennifer\",\n    \"children\": [{\n        \"age\": \"12\",\n        \"name\": \"Jimmy\",\n        \"gender\": \"male\"\n    }],\n    \"father\": \"Joe\"\n}"

これは、改行エスケープ シーケンスを追加し、二重引用符を配置します (ただし、改行の後に 4 つのスペースがありますが、すべてが 1 行にあるようにインデントする必要はありません)。

誰かが私を正しい方向に向けることができれば幸いです。

4

2 に答える 2

4

私が起こっていると思うのは、現在構成されているメッセージ本文リーダーが、メソッドから返された文字列を取得し、有効なJSON文字列になるように適切にエスケープしていることです(jsonは文字列定数内に改行を入れないため)。

これがあなたがすることです...私はあなたがジャクソンの含まれているメッセージボディライターを使用していると仮定しています。(例:JacksonJsonProvider)

次のように、PrettyPrintingを有効にしてObjectMapperインスタンスを設定する@Providerを作成します。

@Provider
public class JacksonObjectMapperProvider implements ContextResolver<ObjectMapper> {

    /**
     * {@inheritDoc}
     */
    @Override
    public ObjectMapper getContext(final Class<?> type) {
        final ObjectMapper toReturn = new ObjectMapper();
        toReturn.enable(SerializationFeature.INDENT_OUTPUT); // This is the important setting
        toReturn.disable(MapperFeature.USE_ANNOTATIONS); // I have this one on but it's probably for other resources in the container testing it in, I don't know if you'd need it.
        return toReturn;
    }
}

次に、リソースが解決されたファミリオブジェクトをJsonに変換しようとするのではなく、返すようにします...メッセージボディライターにそれを実行させます...つまり

public class MyWebService {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Family getFamily() 
        return FamilyUtil.getFamily()
    }
}

と出来上がり:

$ curl http://<server>/<ctx-root>/<path>
{
  "father" : "Joe",
  "mother" : "Jennifer",
  "children" : [ {
    "name" : "Jimmy",
    "age" : "12",
    "gender" : "male"
  } ]
}

ここで、ProviderとMessageBodyReaderをJAX-RSアプリケーション構成に登録する方法について説明しましたが、Jerseyのサーブレットを使用しているか、カスタムアプリケーションを使用しているか、Guiceを使用しているか、その他の設定方法によって大きく異なる可能性があります。 JAX-RSスタック。

于 2012-12-14T05:00:05.980 に答える