Enum "لا يحتوي على مُنشئ افتراضي بدون وسيطات" مع Jaxb وcxf

StackOverflow https://stackoverflow.com/questions/1429509

  •  07-07-2019
  •  | 
  •  

سؤال

يواجه أحد العملاء مشكلة في تشغيل java2ws على بعض التعليمات البرمجية الخاصة به، والتي تستخدم وتوسع الفئات التي يتم استهلاكها من خدمات الويب SOAP الخاصة بي.الخلط حتى الآن؟:)

أنا أكشف عن خدمة ويب SOAP (JBoss5، Java 6).يستهلك شخص ما خدمة الويب هذه باستخدام Axis1 ويقوم بإنشاء جرة منها تحتوي على أنواع البيانات وكعب العميل.ثم يقومون بعد ذلك بتحديد نوعهم الخاص، والذي يمتد إلى أحد أنواعي.النوع الخاص بي يحتوي على تعداد.

class MyParent {
 private MyEnumType myEnum;

 // getters, settters for myEnum;
 }

 class TheirChild extends MyParent {
 ...
 }

عندما يقومون بتشغيل java2ws على الكود الخاص بهم (والذي يمتد إلى صفي)، فإنهم يحصلون على

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.foo.bar.MyEnuMType does not have a no-arg default constructor.
    this problem is related to the following location:
            at net.foo.bar.MyEnumType
            at public net.foo.bar.MyEnumType net.foo.bar.MyParent.getMyEnum()

التعداد الذي حددته موجود أدناه.هذه هي الطريقة التي تظهر بها الآن بعد استهلاكها، ولكن هذه هي الطريقة التي قمت بتحديدها على خادم التطبيق:


@XmlType(name = "MyEnumType")
@XmlEnum
public enum MyEnumType {

    Val1("Val1"),
    Val2("Val2")

    private final String value;

    MyEnumType(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static MyEnumType fromValue(String v) {
        if (v == null || v.length() == 0) {
            return null;
        }

        if (v.equals("Val1")) {
            return MyEnumType.Val1;
        } 
        if (v.equals("Val2")) {
            return MyEnumType.Val2;
        }  
        return null;
    }
}

لقد رأيت أشياء عبر الإنترنت ومنشورات أخرى، مثل (هذا) فيما يتعلق بعدم قدرة Jaxb على التعامل مع القوائم أو أشياء من هذا القبيل، لكنني في حيرة من أمري بشأن التعداد الخاص بي.أنا متأكد تمامًا من أنه لا يمكنك الحصول على مُنشئ افتراضي للتعداد (حسنًا، على الأقل مُنشئ عام بدون وسيطات، تصرخ Java في وجهي عندما أحاول)، لذلك لست متأكدًا مما يجعل هذا الخطأ ممكنًا.أيه أفكار؟

أيضًا، قد يكون السبب في "عددين من IllegalAnnotationsExceptions" هو أن الكود الخاص بي يحتوي في الواقع على تعدادين مكتوبين بشكل مشابه، لكنني تركتهما خارج هذا المثال للإيجاز.

هل كانت مفيدة؟

المحلول

وليس لدى منشئ عدم وسيطة لJAXB أن public، ويمكن private:

private String value;
private MyEnumType() {} // for JAXB

MyEnumType(String v) {
    value = v;
}

وأنت لا يمكن أن تبقي عضو value final بهذه الطريقة، وإن كان.

نصائح أخرى

وأنا واثق من أنك يمكن أن يكون منشئ افتراضي لالتعداد. في الواقع، وهذا ما لديك عندما كنت لا تعرف منشئ explicitely (مثل لك مع معلمة سلسلة).

ويمكنك أيضا أن العديد من الصانعين، لا أحد-وسائط وغيرها.


في المثال الدقيق تعطي، فإنه سيكون بسيطة لتجنب المعلمة سلسلة تماما. طريقة قدمت اسم () له بالضبط قيمة يتم توفيرها لك. سيكون رمز يكون أكثر بساطة:

    @XmlType(name = "MyEnumType")
    @XmlEnum
    public enum MyEnumType {

    Val1, Val2;

    public String value() {
      return name();
    }

    public static MyEnumType fromValue(String v) {
      for(MyEnumType type : values()) {
        if (type.value().equals(v)) {
          return type;
        }
      }
      return null;
    }
   }

إذا كان لديك حقا بعض المعلمات معقدة لتحديد إلى كل قيمة، ولا يمكن أن يكون الصانعين محددة بسبب وجود مكتبة، يمكنك أيضا تخزين قيم متفاوتة الخاص بك إلى EnumMap، وقراءة هذا حسب الحاجة.

عند إجراء from-Java-to-wsdl، يتحقق Apache في البداية مما إذا كان فئة التعداد أم لا، وفقط في حالة فشل هذا الفحص، فإنه يتحقق من المُنشئ.يمكنك رؤيته في org.Apache.axis.wsdl.fromJava.Types::isBeanCompatible.أي رجل عادي، سوف يعتقد ذلك إذا كتب

public enum MyEnum{} 

وسوف يكون كافيا.لكن مطوري Apache لا يعتقدون ذلك (قد يكون سبب IDK هو بعض أسباب التوافق).يقومون بهذه الطريقة - org.apache.axis.utils.JavaUtils::isEnumClassSub.

إذا قمت بتفكيك هذه الفئة، فسترى أن التعداد الخاص بك

  1. يجب تنفيذ String public getValue() {return name();}
  2. يجب تنفيذ MyEnum العام fromString(String v){return valueOf(v);}
  3. لا يمكن أن تحتوي على مجموعة فارغة عامة (){}
  4. يجب تنفيذ String toString()، ولكن كل كائن ينفذها.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top