/ / Mylisz się, jak używać adaptera JAXB XML do moich wymagań - xml, jaxb, jaxb2, xmladapter

Zmieszany jak używać adaptera JAXB XML dla mojego wymagania - xml, jaxb, jaxb2, xmladapter

Używam JAXB do procesu unmarshalling, dla którego żądanie pochodzi z interfejsu użytkownika do naszej klasy usług. Poniżej znajduje się format żądania XML.

<SampleRequest  user="testUser"  account="testAccount"    Specifier=  "value1a,value1b,value1c : name2a,value2b,value2c"/>

Moim wymaganiem jest to, że atrybut Specifier ma wiele serii wartości (: oddzielone dwukropkiem) Muszę zmapować każdą serię wartości na moją niestandardową klasę Java

Próbowałem w ten sposób

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleRequest {

@XmlAttribute
private String user;

@XmlAttribute
private String account;


@XmlAttribute(name="Specifier")
private List<Specifier> specifier;


}

Specifier.java

@XmlJavaTypeAdapter(SpecifierAdapter.class)
public class Specifier {



}

SpecifierAdapter.java

public class SpecifierAdapter  extends XmlAdapter{

@Override
public Object marshal(Object arg0) throws Exception {
// TODO Auto-generated method stub
return null;
}

@Override
public Object unmarshal(Object arg0) throws Exception {
// TODO Auto-generated method stub
return null;
}

}

Część edytowana

Specyfikator klasy ma 3 właściwości typu String.

class Specifier
{
String value1;
String value2;
String value3;
}

I potrzebuję na przykład każdej serii Specyfikatorów (wartość1a, wartość1b, wartość1c) należy zamapować odpowiednio na wartość1, wartość2, wartość3

Edytowana część 3

Cześć , Dzięki za odpowiedź, próbowałem usunąć ten przykład, stwierdziłem, że otrzymuję wartość zerową

To jest prośba, którą przeszedłem

<sampleRequest user="user" account="account" Specifier="v1,v2,v3 : a1,a2,a3"/>

Chcę się tylko upewnić, czy moja klasa Specifier jest poprawna, czy nie? (Ponieważ nie użyłem tutaj żadnych adnotacji)

package com;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlJavaTypeAdapter(SpecifierAdapter.class)
public class Specifier {


Specifier(String v1 , String v2 , String v3)
{

}

String value1;

public String getValue1() {
return value1;
}

public void setValue1(String value1) {
this.value1 = value1;
}

public String getValue2() {
return value2;
}

public void setValue2(String value2) {
this.value2 = value2;
}

public String getValue3() {
return value3;
}

public void setValue3(String value3) {
this.value3 = value3;
}

String value2;
String value3;

}

Odpowiedzi:

7 dla odpowiedzi № 1

UWAGA: Kod adaptera można uprościć, używając bibliotek guava Stolarz i rozłupywacz.

Prośba o próbkę

public class SampleRequest
{
@XmlAttribute
private String user;

@XmlAttribute
private String account;

@XmlAttribute(name = "Specifier")
@XmlJavaTypeAdapter(SpecifierAdapter.class)
private List<Specifier> specifier;
}

Adapter

public class SpecifierAdapter extends XmlAdapter<String, List<Specifier>>
{
@Override
public List<Specifier> unmarshal(final String v) throws Exception
{
String[] values = v.split(":");
List<Specifier> l = new ArrayList<Specifier>();
for (String s : values)
{
String[] vs = s.split(",");
l.add(new Specifier(vs[0], vs[1], vs[2]));
}
return l;
}

@Override
public String marshal(final List<Specifier> v) throws Exception
{
String values = "";
for (Specifier s : v)
{
values += s.getValue1() + "," + s.getValue2() + "," + s.getValue3() + " : ";
}
return values.length() > 0 ? values.substring(0, values.length() - 3) : values;
}
}

Stosowanie

public static void main(final String a[]) throws JAXBException
{
SampleRequest r = new SampleRequest();
r.setAccount("account");
r.setUser("user");
List<Specifier> sps = new ArrayList<Specifier>();
sps.add(new Specifier("v1", "v2", "v3"));
sps.add(new Specifier("a1", "a2", "a3"));
r.setSpecifier(sps);

JAXBContext jc = JAXBContext.newInstance(SampleRequest.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(r, System.out);
}

Wydajność

<?xml version="1.0" encoding="utf-8"?>
<sampleRequest user="user" account="account" Specifier="v1,v2,v3 : a1,a2,a3"/>

2 dla odpowiedzi nr 2

Moja odpowiedź została przygotowana w moim IDE.

Usunąłeś swoje pytanie (11887278) i zadałeś ponownie.

Pomyślałem i uważam, że ten wymóg nie jest dobrym pomysłem. Zainteresowało mnie tylko twoje pytanie, ponieważ nigdy nie robiłem tych wielokrotnych ciągów do atrybutu.

Co ciekawe, mój kod jest dokładnie taki sam, jak wyjaśnił Senthil Kumar.

Zobacz pełny projekt zmavenizowany pod adresem https://code.google.com/p/jinahya/source/browse/trunk/com.googlecode.jinahya/stackoverflow/src/main/java/com/googlecode/jinahya/stackoverflow/q11887278/

Proszę

package com.googlecode.jinahya.stackoverflow.q11887278;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.annotation.adapters.XmlAdapter;


/**
*
* @author Jin Kwon <jinahya at gmail.com>
*/
public class SpecifierAdpater extends XmlAdapter<String, List<Specifier>> {


@Override
public List<Specifier> unmarshal(final String value) throws Exception {

if (value == null) {
return null;
}

final List<Specifier> bound = new ArrayList<Specifier>();
for (String split : value.split(":")) {
final Specifier specifier = new Specifier();
specifier.fromString(split);
bound.add(specifier);
}
return bound;
}


@Override
public String marshal(final List<Specifier> bound) throws Exception {

if (bound == null) {
return null;
}

final StringBuilder builder = new StringBuilder();
final Iterator<Specifier> specifiers = bound.iterator();
if (specifiers.hasNext()) {
builder.append(specifiers.next().toString());
}
while (specifiers.hasNext()) {
builder.append(":");
builder.append(specifiers.next().toString());
}
return builder.toString();
}


}

Oto 10 przykładów, z których każdy jest uporządkowany i nieudany

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request user="user"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request user="user" account="account"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request specifiers="null,null,value3:null,value2,value3"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request specifiers="value1,null,value3"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request user="user" account="account" specifiers="value1,null,null"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request user="user" account="account" specifiers="null,null,null"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request specifiers="null,value2,value3"/>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<request user="user" account="account"/>

1 dla odpowiedzi nr 3

Możesz wypróbować następującą implementację dla SpecifierAdapter.java

public class SpecifierAdapter extends XmlAdapter<String, List<Specifier>>{
@Override
public String marshal(List<Specifier> values) throws Exception {
StringBuilder result = new StringBuilder();
for(Specifier specifier : values) {
result.append(specifier.toString()); //assuming you have overridden toString() method
result.append(",");
}
return result.length>0? result.substring(0, result.length() - 1): "";
}

@Override
public List<Specifier> unmarshal(String colonSeparated) throws Exception {
List<String> values =  Arrays.asList(colonSeparated.split(":"));
List<Specifier> specifiers = new ArrayList<Specifiers>();
for(String str : values){
specifiers.add(new Specifier(str)); //here use your constructor appropriately
}
return specifiers;
}
}