java - Get current host in XmlAdapter -
is there way of retrieving current base uri in xmladapter? or how archieved?
public class service{ ... @get public myentity getentity() { return em.find(myentity.class, "dummy"); } ... } @xmlrootelement(name = "myentity") public class myentity { @xmljavatypeadapter(myadapter.class) private entity2 entity2ref; ... } public class myadapter extends xmladapter<entity2ref, entity2> { // null shold injected host uri @context uriinfo uri; ... }
below complete example of how done:
xml response
below going demonstrate how following response uri in address
element put in via xmladapter
aware of uriinfo
.
<?xml version="1.0" encoding="utf-8"?> <customer id="1"> <name>jane doe</name> <address>http://localhost:9999/address/123</address> </customer>
java model
below java model use example.
customer
by default contents of address
class marshalled beneath customer
element. use xmladapter
perform special handling this.
import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.xmljavatypeadapter; @xmlrootelement @xmltype(proporder={"name", "address"}) public class customer { private int id; private string name; private address address; @xmlattribute public int getid() { return id; } public void setid(int id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } @xmljavatypeadapter(addressadapter.class) public address getaddress() { return address; } public void setaddress(address address) { this.address = address; } }
address
import javax.xml.bind.annotation.xmlattribute; public class address { private int id; @xmlattribute public int getid() { return id; } public void setid(int id) { this.id = id; } }
xmladapter
below xmladapter
use. notice how gets information addressresource
building uri
. requires uriinfo
, makes stateful. need set instance of xmladapter
on marshaller
work correctly.
import javax.ws.rs.core.*; import javax.xml.bind.annotation.adapters.xmladapter; public class addressadapter extends xmladapter<string, address> { private uriinfo uriinfo; public addressadapter() { } public addressadapter(uriinfo uriinfo) { this.uriinfo = uriinfo; } @override public address unmarshal(string v) throws exception { // todo auto-generated method stub return null; } @override public string marshal(address v) throws exception { if(null == uriinfo) { return ""; } uribuilder builder = uribuilder.fromresource(addressresource.class); system.out.println(uriinfo.getabsolutepath().gethost()); builder.scheme(uriinfo.getabsolutepath().getscheme()); builder.host(uriinfo.getabsolutepath().gethost()); builder.port(uriinfo.getabsolutepath().getport()); builder.path(addressresource.class, "get"); return builder.build(v.getid()).tostring(); } }
jax-rs services
in example there 2 services 1 address
, customer
.
addressresource
import javax.ws.rs.*; import javax.ws.rs.ext.provider; @provider @path("/address") public class addressresource { @get @path("{id}") public address get(@pathparam("id") int id) { address address = new address(); address.setid(id); return address; } }
customerresource
since have stateful xmladapter
can't leverage jaxb through default binding. instead can access jaxb through streamingoutput
.
import javax.ws.rs.*; import javax.ws.rs.core.*; import javax.ws.rs.ext.provider; import javax.xml.bind.*; @provider @path("/customer") public class customerresource { private jaxbcontext jaxbcontext; public customerresource() { try { jaxbcontext = jaxbcontext.newinstance(customer.class); } catch (jaxbexception e) { // todo - handle exception } } @get @path("{id}") @produces(mediatype.application_xml) public streamingoutput get(@context uriinfo uriinfo, @pathparam("id") int id) { customer customer = new customer(); customer.setid(id); customer.setname("jane doe"); address address = new address(); address.setid(123); customer.setaddress(address); return new mystreamingoutput(jaxbcontext, customer, uriinfo); } }
streamingoutput
import java.io.*; import javax.ws.rs.webapplicationexception; import javax.ws.rs.core.*; import javax.xml.bind.*; public class mystreamingoutput implements streamingoutput { private jaxbcontext jaxbcontext; private object object; private uriinfo uriinfo; public mystreamingoutput(jaxbcontext jc, object object, uriinfo uriinfo) { this.jaxbcontext = jc; this.object = object; this.uriinfo = uriinfo; } @override public void write(outputstream os) throws ioexception, webapplicationexception { try { marshaller marshaller = jaxbcontext.createmarshaller(); marshaller.setadapter(new addressadapter(uriinfo)); marshaller.marshal(object, os); } catch(jaxbexception jaxbexception) { throw new webapplicationexception(jaxbexception); } } }
Comments
Post a Comment