I have created a webservices which accepts XML data and after some computation over server it adds few fields in xml and returns the output to the client. I am using JAX-RS for Restful webservice and JAXB.
Now the problem is when the response is sent back to the client it doesn't include the newly upadated elemnts.
here is the code detail,
class that represent XML (Using JAXB)
#XmlRootElement(name = "market")
#XmlAccessorType(XmlAccessType.FIELD)
public class IBMarketInfo {
#XmlElement(name="contract")
Contract m_Contract;
#XmlElement(name="tickerId")
int m_tickerId;
#XmlElement(name="tickList")
String m_genericTickList;
#XmlElement(name="snapshot")
boolean m_snapshot;
#XmlElement(name="mktdata") // I AM NOT BE ABLE TO VIEW THIS ELEMENT IN THE RESPONSE
List<String>m_Ticker;
public IBMarketInfo(){
}
public void setTicker(String data){
if (m_Ticker == null) {
m_Ticker = new ArrayList<String>();
}
m_Ticker.add(data);
}
public List<String> getTicker(){
if (m_Ticker == null) {
m_Ticker = new ArrayList<String>();
}
return m_Ticker;
}
public void setTickerId(int tickerid){
m_tickerId = tickerid;
}
public void setGenericTickList(String ticklist){
m_genericTickList = ticklist;
}
public void setSnapshot(boolean snapshot){
m_snapshot=snapshot;
}
public void setContract(Contract contract){
m_Contract = contract;
}
public int getTickerId(){
return m_tickerId;
}
public String getGenericTickList() {
return m_genericTickList;
}
public boolean getSnapShot(){
return m_snapshot;
}
public Contract getContract(){
return m_Contract;
}
}
Restful Webservices request function
public JAXBElement<IBMarketInfo>getMarketData(JAXBElement<IBMarketInfo> info){
MainAccess ma = new MainAccess(); // MainAccess Will pull the data from external server
IBMarketInfo market = info.getValue();
ma.onRequestData(market.getTickerId(),market.getContract(),market.getGenericTickList(),
market.getSnapShot()); // set the user given input from xml
return info;
}
Inside MainAccess class i am doing following
public class MainAccess {
private IBMarketInfo m_marketInfo = new IBMarketInfo(); //declaring in class
// as an when data comes these following functions will add data into List
public void tickSize( int tickerId, int field, int size) {
String msg = EWrapperMsgGenerator.tickSize( tickerId, field, size);
m_marketInfo.setTicker(msg); // setting m_Ticker
}
public void tickPrice( int tickerId, int field, double price, int canAutoExecute) {
String msg = EWrapperMsgGenerator.tickPrice( tickerId, field, price, canAutoExecute);
m_marketInfo.setTicker(msg); //setting m_Ticker
}
}
i have created following Market information object and tried to set values of List in between the code
private IBMarketInfo m_marketInfo = new IBMarketInfo();
m_marketInfo.setTicker(msg);
XML Request
The problem is i am getting the same XML without appending that mktdata
<?xml version="1.0" encoding="UTF-8"?>
<market>
<contract>
<symbol>IBM</symbol>
<sectype>STK</sectype>
<exchange>SMART</exchange>
<currency>USD</currency>
</contract>
<tickerId>1</tickerId>
<tickList>1212,12121</tickList>
<snapshot>false</snapshot>
<ticker-data></ticker-data>
</market>
Your problem is in the following code. MainAccess creates an IBMaretInfo, but you are returning the IBMarkettInfo that was passed in unmodified.
public JAXBElement<IBMarketInfo>getMarketData(JAXBElement<IBMarketInfo> info){
MainAccess ma = new MainAccess(); // MainAccess Will pull the data from external server
IBMarketInfo market = info.getValue();
ma.onRequestData(market.getTickerId(),market.getContract(),market.getGenericTickList(),
market.getSnapShot()); // set the user given input from xml
return info;
}
You model appears to be correctly mapping, since when I run the following code:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(IBMarketInfo.class);
IBMarketInfo ibmi = new IBMarketInfo();
ibmi.setTicker("FOO");
ibmi.setTicker("BAR");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(ibmi, System.out);
}
}
I get the following output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<market>
<tickerId>0</tickerId>
<snapshot>false</snapshot>
<mktdata>FOO</mktdata>
<mktdata>BAR</mktdata>
</market>
Related
I make a POST-type call in eclipse / java using JAX-RS
I can not handle the return in the method predictCid
This method sends the textToPredict parameter and receives a return string, how can I get this value and set it to the variable, textPredicted?
#Path("Predicao")
public class PredicaoCIDResource extends BaseResource {
#POST
#Path("predicaoCid")
public RetornoGenerico<PredicaoCidVo> predizerCid(PredicaoCidVo predicaoVo) {
System.out.print("\nentrou no método java");
RetornoGenerico<PredicaoCidVo> retorno = new RetornoGenerico<PredicaoCidVo>();
String nomeMetodo = "predicaoCid";
super.criarRetornoSucesso(nomeMetodo, retorno);
System.out.print("passou pelo super");
try {
System.out.print("\nentrou no try");
PredicaoCidVo predicaoCidVo = new PredicaoCidVo();
Response retornoPred = predictCid(predicaoVo.getTextToPredict());
System.out.print("retornou do método predict");
predicaoCidVo.setTextPredicted(retornoPred.getEntity().toString());
retorno.setRetorno(predicaoCidVo);
} catch (Exception e) {
super.trataExececao(retorno, e, nomeMetodo);
}
return retorno;
}
#POST
#Path("http://127.0.0.1:5000/predict")
#Consumes("application/x-www-form-urlencoded")
private Response predictCid(#FormParam("textToPredict") String predicaoVo) throws IOException {
System.out.print("\nentrou no método predict");
//How get te return ??? String
}
PredicaoVo:
#XmlRootElement
public class PredicaoCidVo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2471424108047814793L;
private String textToPredict;
private String textPredicted;
public String getTextToPredict() {
return textToPredict;
}
public void setTextToPredict(String textToPredict) {
this.textToPredict = textToPredict;
}
public String getTextPredicted() {
return textPredicted;
}
public void setTextPredicted(String textPredicted) {
this.textPredicted = textPredicted;
}
}
The call is made correctly (predictCid), returns with status 200 (OK).
But, I can not return in one of the class variables PredicaoVo.
How do I make this return by filling in, for example, the textPredicted object?
The return, within the method that does the POST, is a simple string
Below, the feedback I have on SOAPUI testing:
<Response xmlns="http://app-homolog/overcare-ws/rest/Profissional/predicaoCid">
<retorno>
<textPredicted>predicao.PredicaoCidVo#3372c9d7</textPredicted>
<textToPredict null="true"/>
</retorno>
<retornoMensagem>
<dsMensagem>predicaoCid.sucesso</dsMensagem>
<dsStackTrace null="true"/>
<dsTitulo>predicaoCid.titulo</dsTitulo>
<idCamada>SUCESSO</idCamada>
</retornoMensagem>
</Response>
Who sends the return to the soapUI is the method predizerCid
Am having two properties of a bean but one is getting parsed value from XML and another is not getting using Digester in java Please help to solve this issue.
Output
podate:08021988:odate:null
XML File
<Header>
<PODate>08021988</PODate>
<PODate1>08021988</PODate1>
</Header>
Digester Setters
digester.addBeanPropertySetter( "ECnetPO/Header/PODate","podate");
digester.addBeanPropertySetter( "EcnetPO/Header/PODate1","podate1");
digester.addSetNext( "ECnetPO/Header", "addPO" );
Print
public void addPO( YESBarePO po ) {
System.out.println("podate:"+po.getPodate()+":odate:"+po.getPodate1());
}
Bean Info
private String podate;
private String podate1;
public String getPodate()
{
return podate;
}
public void setPodate(String podate)
{
this.podate = podate;
}
public String getPodate1()
{
return podate1;
}
public void setPodate1(String podate1)
{
this.podate1 = podate1;
}
Is it possible to filter what tika parses by the id attribute of div tags in the html?
I am trying to filter out divs with the id "header" because all the pages i am parsing have the same header and I only need the unique data.
I have already triggered the ContentHandler.StartElement for the div tags:
class MyHtmlMapper extends DefaultHtmlMapper {
public String mapSafeElement(String name) {
if ("DIV".equals(name)) {
return "div";
}
return super.mapSafeElement(name);
}
}
And I create the parser with the following:
InputStream urlInput = new URL(url).openStream();
Parser parser = new AutoDetectParser();
Metadata metadata = new Metadata();
ContentHandler handler = new BodyContentHandler();
ParseContext context = new ParseContext();
context.set(HtmlMapper.class, new MyHtmlMapper());
So I am assuming I have to override the BodyContentHandler.startElement() and BodyContentHandler.endElement() methods in the data handler (Something like the following):
class MyContnentHandler extends BodyContentHandler{
public void startElement(String uri, String name, String element, Attributes atri) {
...
super.startElement(...)
}
public void endElement(...)
... //Similar to above
}
}
I've been working on this for a little while and I'm just not terribly familiar with tika. If anyone has any suggestions or solutions they'd be greatly apprecieated!
I later learned that I could make the attributes (i.e. id and class) show up in startElement by overriding the mapSafeAttribute method in the MyHtmlMapper class as follows:
class MyHtmlMapper extends DefaultHtmlMapper {
public String mapSafeElement(String name) {
if ("DIV".equals(name)) {
return "div";
}
return super.mapSafeElement(name);
}
public String mapSafeAttribute(String eleName, String attrName) {
HashSet<String> safeAttrs = new HashSet<String>();
safeAttrs.add("id");
safeAttrs.add("class");
if (safeAttrs.contains(attrName) && eleName.equals("div")) {
return attrName;
} else {
return super.mapSafeAttribute(eleName, attrName);
}
}
}
But I still cannot figure out how to stop the parser from parsing up the things in-between the start and end tag of the with a given attribute property.
Let me know if I've left out any information that would be useful.
class MyHtmlMapper extends DefaultHtmlMapper {
public public boolean isDiscardElement(String name) {
//put here not wanted attributes
HashSet<String> discardAttrs = new HashSet<String>();
if (discardAttrs.contains(name) && eleName.equals("div")) {
return true;
}
return false;
}
)
http://tika.apache.org/1.2/api/index.html?org/apache/tika/parser/html/HtmlParser.html
I want to implement a method which returns JAXBElement following is the code
#XmlRootElement(name = "history")
#XmlAccessorType(XmlAccessType.FIELD)
public class IBHistoryInfo {
#XmlElement(name="trade")
private List<IBTradeInfo> mTrade;
public void updateTradeValue(int reqId, String date, double open, double high, double low,
double close, int volume, int count, double WAP, boolean hasGaps){
IBTradeInfo info = new IBTradeInfo();
info.setReqId(reqId);
info.setDate(date);
info.setOpen(open);
info.setHigh(high);
info.setLow(low);
info.setClose(close);
info.setVolume(volume);
info.setCount(count);
info.setWap(WAP);
info.setHasGaps(hasGaps);
this.setTradeInfo(info);
}
public void setTradeInfo(IBTradeInfo tradeinfo){
mTrade.add(tradeinfo);
}
public List<IBTradeInfo> getTradeInfo(){
if (mTrade == null) {
mTrade = new ArrayList<IBTradeInfo>();
}
return this.mTrade;
}
}
Now i don't know how to creat a method which returns JAXBElement in the above class
for example
public JAXBElement<IBTradeInfo> getTradeXML(){
return mTrade
}
The following is how you could implement the getTradeXML() method:
public JAXBElement<IBTradeInfo> getTradeXML(){
if(null == mTrade || mTrade.size() == 0) {
return null;
}
IBTradeInfo tradeInfo = mTrade.get(0);
QName qname = new QName("http://www.example.com", "trade-info");
return new JAXBElement(qname, IBTradeInfo.class, tradeInfo);
}
I believe, you can only return 1 element at a time. In this case, you possibly need to write something like:
public JAXBElement<IBTradeInfo> getTradeXML(){
return new JAXBElement<IBTradeInfo>(mTrade.get(0), IBTradeInfo.class);
}
Just a guess.
Yesterday I tried to use the client side of the RestEasy framework. The interface has a method:
#PUT
#Path("document/autoincrement")
#Consumes("application/xml")
BaseClientResponse<String> insertPointOfInterest(PoiDocument poiDocument);
and the call to some (Jersey) rest service looks like:
String restServerServiceUrl = "http://my.jersey.server/rest/serviceFoo/v1/";
NSSClientService client = ProxyFactory.create(NSSClientService.class, restServerServiceUrl);
PoiDocument poiDocument = new PoiDocument("Parkirišče", "90", 390262.85133115170, 42240.33558245482);
BaseClientResponse<String> response = client.insertPointOfInterest(poiDocument);
assert response.getResponseStatus() == Response.Status.OK;
// Expected result
//<?xml version="1.0" encoding="UTF-8" standalone="yes"?><insertedRecord><record>14</record></insertedRecord>
logger.info("Returned: " + response.getEntity());
And the logger prints:
14
Kind of expected.
But I want an object not a string, so I can easely assert the values returned. The interface:
#PUT
#Path("document/autoincrement")
#Consumes("application/xml")
BaseClientResponse<InsertedResponse> insertPointOfInterest(PoiDocument poiDocument);
Instead of String there is now a InsertedResponse class which looks like:
#XmlRootElement(name="insertedRecord")
public class InsertedResponse extends ResponseResult{
String insertedRecord;
public InsertedResponse(int insertedRecord) {
this.insertedRecord = Integer.toString(insertedRecord);
}
public InsertedResponse(){
insertedRecord = "";
}
#XmlElement(name="record")
public String getInsertedRecords(){
return insertedRecord;
}
public void add(int recNo) {
insertedRecord = Integer.toString(recNo);
}
}
...and its superclass:
#XmlRootElement(name = "result")
public abstract class ResponseResult {
protected String getClearString(String string) {
if (string != null) {
return Constants.removeInvalidXMLCharacters(string);
}
return "";
}
}
Now, when I change the client call also to:
BaseClientResponse<InsertedResponse> response = client.insertPointOfInterest(poiDocument);
logger.info("Returned: " + response.getEntity().getInsertedRecords());
I get an empty string instead of some value.
So, the question is - where did the value of go? It should print a number, like 14 in the above example.
One missing JAXB annotation (#XmlSeeAlso)
#XmlRootElement(name = "result")
#XmlSeeAlso( { InsertedResponse.class, OtherChild.class, SomeOtherChild.class })
public abstract class ResponseResult {
...
}
and an added setter method
#XmlRootElement(name="insertedRecord")
public class InsertedResponse extends ResponseResult{
...
public void setInsertedRecords(String insertedRecord) {
this.insertedRecord = insertedRecord;
}
solved the problem.