web-dev-qa-db-ja.com

文字列値からJava.util.Dateのインスタンスを構築できません-有効な表現ではありません

冗長な質問のようで申し訳ありませんが、私には多くのオプションがあります。数十のスレッドを読んでいるにもかかわらず、何をすべきか理解できません。

私はJavaアプリケーションがあり、どのジョブを実行するのか:

  1. SOAP WS(XML))からデータを取得し、
  2. いくつかのロジックを実行します(着信deliverydateはdateblになります)
  3. 最後に、それをREST WS(JSON形式)に送信します。これにより、Oracleテーブルが更新されます。

したがって、計画は次のとおりです。
SOAP WS---- deliverydate ---->Java APP(ロジック)---- datebl ---->REST WS

Java APPで使用されるjarはjackson-core-asl-1.9.13.jarおよびjackson-mapper-asl-1.9.13.jarとりわけ。

私が持っている問題は日付を扱うときです。

リーディング:(インスピレーションを得ようとしましたが、ジャクソンのバージョンは同じではないようです):

JSONをカスタム形式でシリアル化(文字列値からJava.util.Dateのインスタンスを構築できません)

Jackson 2.3.2:日付形式をObjectMapperに設定したにもかかわらず、日付の逆シリアル化に関する問題

編集01/04/15

http://jackson-users.ning.com/forum/topics/cannot-deserialize-a-date

今の事実

ポイント1:SOAP WSからデータをリカバリする場合、deliverydateはStringであり、正確な値は次のとおりです。

2014-07-31 07:00:00.0

ポイント2:セッターを使用する直前に、この文字列を日付にフォーマットすることをお勧めします。

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    Date dateebl = dateFormat.parse(deliverydate);
                                    msi.setDatebl(dateebl);

pOJOでのdatebl宣言

private Java.util.Date    datebl;

この段階で、datebl値は

7月31日木曜日07:00:00 CEST 2014

(特定の形式yyyy-MM-dd HH:mm:ssを選択しているにもかかわらず)

ポイント3とエラー:残りのサーバーがスローしたエラー:

文字列値「Thu Jul 31 07:00:00 CEST 2014」からJava.util.Dateのインスタンスを構築できません:有効な表現ではありません(エラー:日付「Thu Jul 31 07:00:00 CEST 2014」を解析できません:標準形式( "yyyy-MM-dd'T'HH:mm:ss.SSSZ"、 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z '"、 "EEE、 dd MMM yyyy HH:mm:ss zzz "、" yyyy-MM-dd "))at [ソース:org.glassfish.jersey.message.internal.EntityInputStream@5709779;行:1、列:74](参照チェーンを通じて:com.rest.entities.MvtSwapsIn ["datebl"])

私がやろうとしたこと:これを解決するには、2.xより前のバージョンを使用しているので、私の最善のオプションはカスタムシリアライザなので、

  • Pojoでは、ゲッターの直前に注釈が追加されました

    @JsonSerialize(using = CustomJsonDateSerializer.class)
        public Java.util.Date getDatebl() {
            return datebl;
        }
    
  • シリアライザは次のように作成されました

    public class CustomJsonDateSerializer extends JsonSerializer<Date> {
    
    @Override
    public void serialize(Date value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(Properties.General.FORMAT_HEURE_JSON_SERIALIZE_2);
        String dateString = dateFormat.format(value);
        jgen.writeString(dateString);       
    }
    

    }

例では、FORMAT_HEURE_JSON_SERIALIZE_2で試してみましたが、他の多くを試しても成功しませんでした。

public static final String  FORMAT_HEURE_JSON               = new String("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static final String  FORMAT_HEURE_JSON_SERIALIZE     = new String("EEE yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static final String  FORMAT_HEURE_JSON_SERIALIZE_2   = new String("EEE, dd MMM yyyy HH:mm:ss zzz");
public static final String  FORMAT_HEURE_JSON_SERIALIZE_3   = new String("yyyy-MM-dd HH:mm:ss");

この時点で、私は迷っています。

コードを更新する場所と方法がわかりません。

  1. SOAP wsから日付を取得した後もSimpleDateFormatを使用する必要がありますか?
  2. ジャクソン1.9を使用しているという事実を考えると、私の@JsonSerializeアノテーションは良いですか? (シリアライザと同様に?)
  3. 残りのサーバーで何かを変更する必要がありますか?

誰かが私の考えを整理するのを手伝ってくれませんか?

敬具、

ピエール

7
Tanc

POJOを開き、日付フィールド宣言に次のように注釈を付けます

@JsonFormat
  (shape = JsonFormat.Shape.STRING, pattern = "<your_date_pattern>")

Your_date_patternは次のようになります

yyyy-MM-dd HH:mm:ss

できた

8

JerseyをJAX-RS実装として使用していると思います。スタックトレースからいくつかの詳細を省略しましたか?スタックトレースを読むと、ジャージーが日付ではなく文字列を受け取るようです:Can not construct instance of Java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014'。クラスの場合com.rest.entities.MvtSwapsIn["datebl"])は日付を宣言しますが、この動作は少し奇妙です。

とにかく、ジャクソンが機能するための1つの提案は、REST ConfigとContextResolverを使用して、Jackson ObjectMapperを登録することです(これは、Jackson 1.xと2.xの両方に適用されます)。コンストラクタとgetContext()メソッドの両方で、実行時に呼び出されるかどうかを確認します。

public class ObjectMapperConfigContextResolver implements     ContextResolver<ObjectMapper> {

ObjectMapper mapper;

public ObjectMapperConfigContextResolver() {
    mapper.setDateFormat(new SimpleDateFormat("<your pattern>"));
}

@Override
public ObjectMapper getContext(Class<?> type) {
    return mapper;
}

}

@Providerアノテーションは、JAX-RSに構成済みのObjectMapperを選択させる必要があります。手動で実行できない場合:

@ApplicationPath("/")
public class RestApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<>();
        classes.add(ObjectMapperConfigContextResolver.class);
        return classes;
    }
}

Pom.xmlから情報を提供した場合(Mavenを使用している場合)は役に立ちます。

1
thomas77

ジム、ジョン、どうもありがとう。

トーマス。回避策を見つけた場合でも、あなたが書いた内容を注意深く確認します。

それにもかかわらず、私は最終的にこれを解決することができました。問題がSerialization(JavaApp)にあるかどうかを理解できなかったので、反対側のDeserialization(REST WS)を確認することにしました。

クイックリマインダー:SOAP WS ----> Java APP- -> REST WS

SOAPから受信した日付WSは文字列として正確に受信され、その値は

2014-07-31 07:00:00.0

Java App内では、

            DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
            DateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = originalFormat.parse(deliverydate);
            String formattedDate = targetFormat.format(date); 

            msi.setDatebl(date);

この時点で、JSONがREST WSに送信されたことを確認するまで、同じエラーが発生しました

{"id":87434958,"datebl":"Thu Jul 31 07:00:00 CEST 2014","price":15.45,"model":"AAA"}

* JSONオブジェクトの一部が切り取られました。

REST WS内で、以下をpojoに追加し(おそらくそのうちの1つが必要です)、次のようにカスタムデシリアライザを作成しました。

@JsonDeserialize(using = CustomJsonDateDeserializer.class)
private Java.util.Date    datebl;

@JsonDeserialize(using = CustomJsonDateDeserializer.class)
public void setDatebl(Java.util.Date datebl) {
    this.datebl = datebl;
}



import Java.io.IOException;
import Java.text.DateFormat;
import Java.text.ParseException;
import Java.text.SimpleDateFormat;
import Java.util.Date;
import Java.util.Locale;

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;



public class CustomJsonDateDeserializer extends JsonDeserializer<Date>
{
    @Override
    public Date deserialize(JsonParser jsonparser,
            DeserializationContext deserializationcontext) throws IOException, JsonProcessingException {

        DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
        String dateStr = jsonparser.getText();
        try {
            return (Date)formatter.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }
}

この時点で、更新は適切に行われています。データベースに適切な形式で日付が見つかりました。

測定値:「Mon Jun 18 00:00:00 IST 2012」を18/06/2012に変換する方法

0
Tanc