首先,我已经看过这里了:
有关使用JodaTime
处理JAXB
类的一些可能的帮助。
我继承了一个带有impl(和XML适配器)类的代码库,如下所示。
尝试使用WSDL
Apache CXF v2.7.2 Maven plugin
生成java2ws
和客户时,我得到以下内容:
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
org.joda.time.base.BaseInterval does not have a no-arg default constructor.
this problem is related to the following location:
at org.joda.time.base.BaseInterval
at org.joda.time.MutableInterval
at com.etp.commons.persistence.model.time.Period
好吧,Period
(下方)扩展MutableInterval
扩展BaseInterval
扩展AbstractInterval
,JodaTime v2.1
中有一个受保护的无参数构造函数。 Period
有一个公共的无参数构造函数,它调用MutableInterval
的构造函数变量传递一些默认值。
有关如何进行的任何提示?
package com.etp.commons.persistence.model.time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableInterval;
import org.joda.time.ReadableInstant;
import org.joda.time.ReadableInterval;
import com.etp.commons.persistence.model.jaxb.XMLPeriodAdapter;
import com.etp.commons.time.services.core.TimeDispatcher;
@XmlType
@XmlJavaTypeAdapter(value=XMLPeriodAdapter.class)
public class Period extends MutableInterval implements Comparable<Period>{
private static final long serialVersionUID = 1L;
public static boolean endpointInclusive = true;
public static DateTime defaultEffectiveInstant = new DateTime(1900,1,1,0,0,0,0, DateTimeZone.forID("GMT"));
public static DateTime defaultTerminationInstant = new DateTime(9999,12,31,0,0,0,0, DateTimeZone.forID("GMT"));
public static Period defaultEffectiveInterval = new Period();
@Override
public boolean contains(ReadableInstant time){
if (endpointInclusive){
return this.getStartMillis() < time.getMillis() && this.getEndMillis() >= time.getMillis();
}else{
return super.contains(time);
}
}
@Override
public boolean contains(long time){
if (endpointInclusive){
return this.getStartMillis() < time && this.getEndMillis() >= time;
}else{
return super.contains(time);
}
}
@Override
public boolean containsNow(){
long time = TimeDispatcher.defaultTimeDispatcher.getCurrentTimeMillis();
if (endpointInclusive){
return this.getStartMillis() < time && this.getEndMillis() >= time;
}else{
return super.contains(time);
}
}
public DateTime getInclusiveTerminalInstant(){
if (endpointInclusive){
return this.getEnd();
}else{
return this.getStart();
}
}
public Period getOverlap(Period period){
if (!this.overlaps(period)){
return null;
}else if (this.contains(period)){
return new Period(period);
}else if (period.contains(this)){
return new Period(this);
}else{
if (this.getStartMillis() < period.getStartMillis()){
return new Period(period.getStart(),this.getEnd());
}else{
return new Period(this.getStart(),period.getEnd());
}
}
}
public Period offsetByJodaPeriod(org.joda.time.Period period, boolean reverse){
Period p = null;
if (reverse){
p = new Period(getStart().minus(period),getEnd().minus(period));
}else{
p = new Period(getStart().plus(period),getEnd().plus(period));
}
return p;
}
public static List<Period> merge(List<Period> periods){
List<Period> result = new ArrayList<Period>();
periods = getDistinctPeriods(periods);
Collections.sort(periods);
DateTime start = null;
DateTime end = null;
for (Period period : periods){
if (start == null){
start = period.getStart();
end = period.getEnd();
}else{
if (period.getStart().isEqual(end)){
end = period.getEnd();
}else{
result.add(new Period(start,end));
start = period.getStart();
end = period.getEnd();
}
}
}
if (start != null){
result.add(new Period(start,end));
}
return result;
}
public static Period getExtentPeriod(Collection<Period> periods){
DateTime start = null;
DateTime end = null;
for (Period period : periods){
if (start == null || start.getMillis() > period.getStartMillis()){
start = period.getStart();
}
if (end == null || end.getMillis() < period.getEndMillis()){
end = period.getEnd();
}
}
return new Period(start,end);
}
public static Period getEnclosingPeriod(DateTime instant, FrequencyUnitType unit){
DateTime start = unit.truncate(instant);
DateTime end = start.plus(unit.getJodaPeriod());
return new Period(start,end);
}
public Period subtractOverlap(Period period){
if (this.overlaps(period)){
if (period.contains(this)){
return null;
}else if (this.contains(period)){
throw new IllegalArgumentException("Period contains target period. More than one period would result from subtract");
}else if (this.getStartMillis() < period.getStartMillis()){
return new Period(this.getStart(),period.getStart());
}else if (this.getEndMillis() > period.getStartMillis()){
return new Period(period.getEnd(),this.getEnd());
}
}
return this;
}
public Period subtractOverhang(Period period){
if (this.overlaps(period)){
if (period.contains(this)){
return this;
}else if (this.contains(period)){
return new Period(period.getStart(),period.getEnd());
}else if (this.getStartMillis() < period.getStartMillis()){
return new Period(period.getStart(),this.getEnd());
}else if (this.getEndMillis() > period.getStartMillis()){
return new Period(this.getStart(),period.getEnd());
}
}
return null;
}
/**
* Returns the smallest period that is common to all of the passed periods and contains the passed time.
*
* @param periods
* @param time
* @return
*/
public static Period getSmallestCommonIntersection(Collection<Period> periods, DateTime time){
Period smallest = new Period();
for (Period period : periods){
if (!period.contains(time)){
return null;
}
if (smallest.getStartMillis() < period.getStartMillis()){
smallest.setStart(period.getStart());
}
if (smallest.getEndMillis() > period.getEndMillis()){
smallest.setEnd(period.getEnd());
}
}
return smallest;
}
public static List<? extends PeriodDatedObject> getCollectionWithinPeriod(Collection<? extends PeriodDatedObject> collection, Period effectivePeriod){
List<PeriodDatedObject> effectiveObs = new ArrayList<PeriodDatedObject>();
for (PeriodDatedObject ob : collection){
if (ob.getPeriod().overlaps(effectivePeriod)){
effectiveObs.add(ob);
}
}
return effectiveObs;
}
public static List<? extends PeriodDatedObject> getCollectionAtInstant(Collection<? extends PeriodDatedObject> collection, DateTime effectiveInstant){
List<PeriodDatedObject> effectiveObs = new ArrayList<PeriodDatedObject>();
for (PeriodDatedObject ob : collection){
if (ob.getPeriod().contains(effectiveInstant)){
effectiveObs.add(ob);
}
}
return effectiveObs;
}
public static PeriodDatedObject getMemberAtInstant(Collection<? extends PeriodDatedObject> collection, DateTime effectiveInstant){
for (PeriodDatedObject ob : collection){
if (ob.getPeriod().contains(effectiveInstant)){
return ob;
}
}
return null;
}
public List<Period> getGaps(List<Period> periods){
Collections.sort(periods);
List<Period> gaps = new ArrayList<Period>();
DateTime contiguousTo = this.getStart();
for (Period period : periods){
if (period.getStart().getMillis() <= this.getStart().getMillis()){
contiguousTo = period.getEnd();
}else if (period.getStart().isEqual(contiguousTo)){
contiguousTo = period.getEnd();
}else if (period.getStartMillis() > contiguousTo.getMillis()){
Period gap = new Period(contiguousTo, period.getStart());
contiguousTo = period.getEnd();
gaps.add(gap);
}
}
if (contiguousTo.getMillis() < this.getEnd().getMillis()){
Period gap = new Period(contiguousTo, this.getEnd());
gaps.add(gap);
}
return gaps;
}
/**
* Returns a list of distinct periods that results from overlaying the list
* of input periods. Non-contiguous periods will not be returned
*
* @param periods
* @return
*/
public static List<Period> getDistinctPeriods(Collection<Period> periods){
Set<Long> instants = new HashSet<Long>();
for (Period period : periods){
instants.add(period.getStart().getMillis());
instants.add(period.getEnd().getMillis());
}
List<Long> sorted = new ArrayList<Long>(instants);
Collections.sort(sorted);
List<Period> distinctPeriods = new ArrayList<Period>();
Period period = null;
for (int i=0;i<sorted.size();i++){
if (period != null){
period.setEnd(new DateTime(sorted.get(i)));
distinctPeriods.add(period);
}
period = new Period();
period.setStart(new DateTime(sorted.get(i)));
}
List<Period> emptyPeriods = new ArrayList<Period>();
for (Period distinctPeriod : distinctPeriods){
boolean empty = true;
for (Period actualPeriod : periods){
if (actualPeriod.contains(distinctPeriod)){
empty = false;
break;
}
}
if (empty){
emptyPeriods.add(distinctPeriod);
}
}
distinctPeriods.removeAll(emptyPeriods);
return distinctPeriods;
}
public boolean abuts(Period period){
return this.getStartMillis() == period.getEndMillis() || this.getEndMillis() == period.getStartMillis();
}
public DateTime getStartDate(){
return this.getStart();
}
public void setStartDate(DateTime date){
this.setStart(date);
}
public DateTime getEndDate(){
return this.getEnd();
}
public void setEndDate(DateTime date){
this.setEnd(date);
}
public Period(){
super(defaultEffectiveInstant,defaultTerminationInstant);
}
public Period(DateTime start, DateTime end){
super(start,end);
}
public Period(long start, long end) {
super(start,end);
}
public Period(ReadableInterval period) {
super(period.getStart(),period.getEnd());
}
@Override
public int hashCode() {
final int prime = 31;
int result = prime;
result = prime * result + new Long(this.getStartMillis()).hashCode();
result = prime * result + new Long(this.getEndMillis()).hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!Period.class.isAssignableFrom(obj.getClass()))
return false;
Period other = (Period) obj;
if (this.getEnd() == null) {
if (other.getEnd() != null)
return false;
} else if (!this.getEnd().isEqual(other.getEnd()))
return false;
if (this.getStart() == null) {
if (other.getStart() != null)
return false;
} else if (!this.getStart().isEqual(other.getStart()))
return false;
return true;
}
public int compareByEnd(Period o) {
return o.getEnd().compareTo(this.getEnd());
}
@Override
public int compareTo(Period o) {
int compare = this.getStart().compareTo(o.getStart());
return compare;
}
public String toString(){
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZZ");
return fmt.format(this.getStart().toDate()) + "-" + fmt.format(this.getEnd().toDate());
}
public String toString(String format){
SimpleDateFormat fmt = new SimpleDateFormat(format);
return fmt.format(this.getStart().toDate()) + "-" + fmt.format(this.getEnd().toDate());
}
public boolean containsIncludingEndpoints(DateTime next) {
return contains(next) || getStart().isEqual(next) || getEnd().isEqual(next);
}
}
这是适配器......
package com.etp.commons.persistence.model.jaxb;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.etp.commons.persistence.model.time.Period;
public class XMLPeriodAdapter extends XmlAdapter<String, Period> {
/*
@Override
public Period unmarshal(JAXBAdaptedPeriod v) throws Exception {
return new Period(new DateTime(v.getStart().getTime()), new DateTime(v.getEnd().getTime()));
}
@Override
public JAXBAdaptedPeriod marshal(Period v) throws Exception {
JAXBAdaptedPeriod period = new JAXBAdaptedPeriod();
if(v!=null){
period.setStart(v.getStart().toDate());
period.setEnd(v.getEnd().toDate());
}
return period;
}
*/
@Override
public Period unmarshal(final String v) throws Exception {
final int dashIndex = v.indexOf('-');
final long start = Long.valueOf(v.substring(0, dashIndex));
final long end = Long.valueOf(v.substring(dashIndex + 1));
return new Period(start, end);
}
@Override
public String marshal(final Period v) throws Exception {
return v.getStartMillis() + "-" + v.getEndMillis();
}
}
更新详情
假设我有这样的服务......
@WebService(targetNamespace="http://www.foo.com/DerivationModelServices")
public interface DerivationModelService extends InternalDerivationModelService{
public Determinant getDeterminant(DeterminantQueryParameters params) throws PersistenceServiceException;
public DeterminantDefinition getDeterminantDefinition(DeterminantDefinitionQueryParameters params) throws PersistenceServiceException;
public Group getGroup(GroupQueryParameters params) throws Exception;
public AttributeDefinition getAttributeDefinition(AttributeDefinitionQueryParameters params) throws PersistenceServiceException;
public void saveGroup(Group group) throws PersistenceServiceException;
public void saveDeterminant(Determinant determinant) throws PersistenceServiceException;
public DerivationModel getDerivationModel(DerivationModelQueryParameters model) throws PersistenceServiceException;
public void saveReportDefinition(ReportDefinition def);
public PagedQueryResults<ReportDefinition> getReportDefinitions(ReportDefinitionsQueryParameters params);
public ReportDefinition getReportDefinition(ReportDefinitionQueryParameters params);
}
为什么我会在Period
上获得no-arg构造函数?此外,如果我用@WebMethod(excluded=true)
标记所有超级接口的方法,以免暴露它们,为什么我会得到这个异常?我问,因为虽然我收到的第一个答案看起来像是要走的路,但我还是没能过去。 (对于所描述的案例,我的代码库中可能没有到处查找?)
答案 0 :(得分:0)
您的POJO中应使用注释@XmlJavaTypeAdapter(value=XMLPeriodAdapter.class)
。
@XmlType
@XmlJavaTypeAdapter(value=XMLPeriodAdapter.class)
class Response
{
private Period period;
// another fields
// setters/getters
}
如果您不想使用单独的POJO,可以使用下一个
@WebMethod
public void wsMethod(@WebParam
@XmlJavaTypeAdapter(XMLPeriodAdapter.class) Period period){}
@WebMethod
@WebResult
@XmlJavaTypeAdapter(XMLPeriodAdapter.class)
public Period wsMethod(){}