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;
}
Related
the external web service returns me a Json file of the form
{"forecasts":[{"period_end":"2021-01-15T01:00:00.0000000Z","period":"PT30M","ghi90":0,"ghi":0,"ghi10":0},{"period_end":"2021-01-15T01:30:00.0000000Z","period":"PT30M","ghi90":0,"ghi":0,"ghi10":0},{"period_end":"2021-01-15T02:00:00.0000000Z","period":"PT30M","ghi90":0,"ghi":0,"ghi10":0}]}
Using RestRespone a transform an json element
RestResponse resp = rest.get(url)
resp.json instanceof JsonElement
How can I create a domain object from the Json element variable, knowing that my wrapper class is
class ForecastGhi {
static constraints = {
}
private ArrayList<IrradianciaGlobalHorizontal> forecast
ArrayList<IrradianciaGlobalHorizontal> getForecast() {
return forecast
}
void setForecast(ArrayList<IrradianciaGlobalHorizontal> forecast) {
this.forecast = forecast
}
}
and de persist domain class is
class IrradianciaGlobalHorizontal {
static constraints = {
}
#JsonProperty("all")
private def period_end
private def period
private def ghi90
private def ghi
private def ghi10
def getGhi() {
this.ghi
}
void setGhi(int ghi) {
this.ghi = ghi
}
def getGhi90() {
this.ghi90
}
void setGhi90(int ghi90) {
this.ghi90 = ghi90
}
def getGhi10() {
this.ghi10
}
void setGhi10(int ghi10) {
this.ghi10 = ghi10
}
def getPeriod_end() {
this.period_end
}
void setPeriod_end(Date period_end) {
this.period_end = period_end
}
def getPeriod() {
this.period
}
void setPeriod(String period) {
this.period = period
}
}
Help please; thanks a lot
This is an issue with your API implementation; The endpoint changed the domain field names &/or domain name. This will cause issues with bringing said data back in.
Either that or front-end is not matching the API docs for the endpoint.
Field names/domain names should match the domain/resource unless you are going for a level of obfuscation and then accept that you are going to need a middle layer to act as a translater (ie EDI).
You want output to be able to be read as input by the same endpoint by merely changing the request method.
My suggestion (easiest solution): change original endpoint to match domain/resource field names
If you have the opportunity to use Jackson library, you can do this:
ForecastGhi request = objectMapper.readValue(jsonAsText, ForecastGhi.class);
Create an objectMapper and configure to fail in case of unknown properties (just in case)
private String getJsonAsTextFromRest() {
String message = " {\"forecasts\":[{\"period_end\":\"2021-01-15T01:00:00.0000000Z\",\"period\":\"PT30M\",\"ghi90\":0,\"ghi\":0,\"ghi10\":0},{\"period_end\":\"2021-01-15T01:30:00.0000000Z\",\"period\":\"PT31M\",\"ghi90\":0,\"ghi\":0,\"ghi10\":0},{\"period_end\":\"2021-01-15T02:00:00.0000000Z\",\"period\":\"PT32M\",\"ghi90\":0,\"ghi\":0,\"ghi10\":0}]}";
return message;
}
#Override
public void run(String... arg0) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String jsonAsText = getJsonAsTextFromRest();
ForecastGhi request = objectMapper.readValue(jsonAsText, ForecastGhi.class);
request.getForecast().stream().forEach(it -> System.out.println(it.getPeriod() + " " + it.getGhi()));
}
public class IrradianciaGlobalHorizontal {
private Date period_end;
private String period;
private int ghi90;
private int ghi;
private int ghi10;
public int getGhi() {
return this.ghi;
}
public void setGhi(int ghi) {
this.ghi = ghi;
}
public int getGhi90() {
return this.ghi90;
}
public void setGhi90(int ghi90) {
this.ghi90 = ghi90;
}
public int getGhi10() {
return this.ghi10;
}
void setGhi10(int ghi10) {
this.ghi10 = ghi10;
}
public Date getPeriod_end() {
return this.period_end;
}
public void setPeriod_end(Date period_end) {
this.period_end = period_end;
}
public String getPeriod() {
return this.period;
}
public void setPeriod(String period) {
this.period = period;
}
}
ForecastGhi class.
import com.fasterxml.jackson.annotation.JsonProperty;
public class ForecastGhi {
private ArrayList<IrradianciaGlobalHorizontal> forecast;
#JsonProperty("forecasts")//It must be the same as the json property
public ArrayList<IrradianciaGlobalHorizontal> getForecast() {
return forecast;
}
#JsonProperty("forecasts")
public void setForecast(ArrayList<IrradianciaGlobalHorizontal> forecast) {
this.forecast = forecast;
}
}
Results:
PT30M 0
PT31M 0
PT32M 0
Dependencies Gradle:
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.1'
Or
Dependencies Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
</dependency>
Note: in your json example you use forecasts, but your java property name is forecast. In that case its necessary to decorate the property with #JsonProperty("forecasts"). If you dont do it, you get an error like this com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "forecasts"
Hello Team,
I recently tried reading contents from application.yml file in a Spring Boot project (Version 2.3.4).
Initially, all the properties from yml file were getting read as null.
After cleaning and rebuilding project several times, I could read all the properties except the List of user defined class object (List<LogComponents> in below class) which is still getting read as null.
I tried all the possible solutions but nothing worked for me.
Could you please check and help me in understanding what I have missed in below code because of which the value for List<LogComponent> logComponents is still getting read as null from yml file?
Thanking you in anticipation!
Configuration Java Class
#Configuration
#EnableConfigurationProperties
#ConfigurationProperties
public class TestAPIConfiguration {
private String eventCache;
private String diskBasedCache;
private List<String> sendAllSMSto;
private List<String> sendAllEmailsto;
//This property is getting read as null even if
//value for this property is present in yml file.
private List<LogComponent> logComponents;
#NotNull
private String selfURIPrefix;
#NotNull
private String investURIPrefix;
#NotNull
private String ifaURIPrefix;
private String apiEnv;
private final Joiner joiner = Joiner.on( "," ).skipNulls();
private static final Logger LOGGER = LoggerFactory.getLogger(TestAPIConfiguration.class);
#PostConstruct
public void setSystemProperties()
{
try
{
System.setProperty(SystemConstants.EVENT_CACHE_PATH, eventCache);
System.setProperty(SystemConstants.DISK_BASED_CACHE_PATH, diskBasedCache);
System.setProperty(SystemConstants.REQUEST_LOGGING_FIELDS,
JSONUtils.getObjectMapper().writeValueAsString(logComponents));
System.setProperty(SystemConstants.ENVIRONMENT_IDENTIFIER, apiEnv);
System.setProperty(INVEST_URI_PREFIX, investURIPrefix);
System.setProperty(IFA_URI_PREFIX, ifaURIPrefix);
if(sendAllSMSto != null)
System.setProperty(SEND_ALL_SMS_TO, joiner.join(sendAllSMSto));
if(sendAllEmailsto != null)
System.setProperty(SystemConstants.SEND_ALL_EMAILS_TO, joiner.join(sendAllEmailsto));
}
catch(Exception se)
{
LOGGER.error("Error in Configuration Setup: {}", se.getLocalizedMessage());
}
}
public String getEventCache() {
return eventCache;
}
public void setEventCache(String eventCache) {
this.eventCache = eventCache;
}
public String getDiskBasedCache() {
return diskBasedCache;
}
public void setDiskBasedCache(String diskBasedCache) {
this.diskBasedCache = diskBasedCache;
}
public List getSendAllSMSto() {
return sendAllSMSto;
}
public void setSendAllSMSto(List<String> sendAllSMSto) {
this.sendAllSMSto = sendAllSMSto;
}
public List getSendAllEmailsto() {
return sendAllEmailsto;
}
public void setSendAllEmailsto(List<String> sendAllEmailsto) {
this.sendAllEmailsto = sendAllEmailsto;
}
public List getRequestLoggingFields() {
return logComponents;
}
public void setRequestLoggingFields(List<LogComponent> requestLoggingFields) {
this.logComponents = requestLoggingFields;
}
public String getSelfURIPrefix() {
return selfURIPrefix;
}
public void setSelfURIPrefix(String selfURIPrefix) {
this.selfURIPrefix = selfURIPrefix;
}
public String getInvestURIPrefix() {
return investURIPrefix;
}
public void setInvestURIPrefix(String investURIPrefix) {
this.investURIPrefix = investURIPrefix;
}
public String getIfaURIPrefix() {
return ifaURIPrefix;
}
public void setIfaURIPrefix(String ifaURIPrefix) {
this.ifaURIPrefix = ifaURIPrefix;
}
public String getApiEnv() {
return apiEnv;
}
public void setApiEnv(String apiEnv) {
this.apiEnv = apiEnv;
}
}
LogComponent Java Class
#Component
public class LogComponent {
#NotNull
private String headerName;
#NotNull
private String sessionKey;
#NotNull
private String logPrintKey;
public String getHeaderName() {
return headerName;
}
public String getSessionKey() {
return sessionKey;
}
public String getLogPrintKey() {
return logPrintKey;
}
}
application.yml File
debug: true
server:
port: 8080
apiEnv: UAT
selfURIPrefix: "https://testurl.localhost.net"
investURIPrefix: "https://testurl.mediaserver.net"
ifaURIPrefix: "https://testurl.secondaryserver.net"
sendAllSMSto:
- "0000000000"
sendAllEmailsto:
- "abc#testmail.com"
eventCache: "C:\\Users\\username\\project\\devnull\\eventcachepurchase.mdb"
diskBasedCache: "C:\\Users\\username\\project\\devnull\\cache.mdb"
logComponents:
- headerName: X-RT-REQUEST-TRACKER
sessionKey: NOT AVAILABLE
logPrintKey: REQUEST-TRACKER
- headerName: X-RT-INX-DWD
sessionKey: IFX-PDR
logPrintKey: PDR_NO
- headerName: X-RT-IFA-ARN
sessionKey: IRX-AXRN
logPrintKey: AXR-CDODEEE
Finally, I found the solution.
I had not created setter methods inside the LogComponent class because of which the values were not getting assigned to the variables.
After adding the setters for all the fields, this issue has been resolved.
I'm consuming a web service using CXF, the thing is that I need to send and XML inside a CDATA tag.
To do it I created an interceptor
public class CDATAInterceptor extends AbstractPhaseInterceptor<Message> {
public CDATAInterceptor() {
super(Phase.MARSHAL);
//addAfter(AttachmentOutInterceptor.class.getName());
}
#Override
public void handleMessage(Message message) {
message.put("disable.outputstream.optimization", Boolean.TRUE);
XMLStreamWriter writer = (XMLStreamWriter) message.getContent(XMLStreamWriter.class);
if (writer != null && !(writer instanceof CDataXMLStreamWriter)) {
message.setContent(XMLStreamWriter.class, new CDataXMLStreamWriter(writer));
}
}
public void handleFault(Message messageParam) {
System.out.println(messageParam);
}
}
I am using a custom CDATAXMLStreamWriter defined as follows:
public class CDataXMLStreamWriter extends DelegatingXMLStreamWriter {
private static final Pattern XML_CHARS = Pattern.compile( "[&<>]" );
public CDataXMLStreamWriter(XMLStreamWriter del) {
super(del);
}
#Override
public void writeCharacters(String text) throws XMLStreamException {
boolean useCData = XML_CHARS.matcher( text ).find();
if (useCData) {
super.writeCData(text);
}else {
super.writeCharacters(text);
}
}
public void writeStartElement(String local) throws XMLStreamException {
super.writeStartElement(local);
}
}
I configured this CDATA interceptor as follows
protected void configureCDataInterceptor() {
CDATAInterceptor inter = new CDATAInterceptor();
ClientProxy.getClient(this.clientProxy).getOutInterceptors().add(inter);
}
The issue I have is that the xml inside CDATA is splitted in multiple parts, somthing like this
<![CDATA[part1ofXML]]><![CDATA[part2ofXML]]><![CDATA[part3ofXML]]>
I tried getting the XML and removing all the newline characters and the XML gets inside one CDATA block, but the issue with this is that this XML is signed, and removing the characters breaks the signature.
I hope this was clear enough, and sorry if the post is hard to understand.
If you can give me one clue to solve this problem it would be great!
Thanks,
Julio
Hi I saw some of the related question related to this but didn't find any to the point solution.
I have a POJO class defined as:
MpsPojo.java
public class MpsPojo {
private String mfr;
private String prod;
private String sche;
public String getMfr() {
return mfr;
}
public void setMfr(String mfr) {
this.mfr = mfr;
}
public String getProd() {
return prod;
}
public void setProd() {
this.prod = prod;
}
public String getSchema() {
return sche;
}
public void setSchema() {
this.sche = sche;
}
}
I have 2nd business Logic as:: MpsLogic.java
public class MpsLogic {
public void calculateAssert(MpsPojo mpspojo){
String manufacturer;
String product;
String schema;
manufacturer = mpspojo.getMfr();
product = mpspojo.getProd();
schema = mpspojo.getSchema();
String url = "http://localhost:9120/dashboards/all/list/"+manufacturer+"/"+product+"/"+schema;
}
}
And final class, the Test class is :: FinalLogic.java
public class FinalLogic {
MpsPojo mpspojon = new MpsPojo();
MpsLogic mpslogicn = new MpsLogic();
#Test
public void firstTest() {
mpspojon.setMfr("m1");
mpspojon.setProd("p1");
mpspojon.setSchema("sch1");
mpslogicn.calculateAssert(mpspojon);
System.out.println("Printing from Final class");
}
}
In program FinalLogic.java, this gives me the Compilation error error method setSchema in class MpsPojo cannot be applied to given types;
But when I comment the lines mpspojon.setProd("p1"); and mpspojon.setSchema("sch1"); then this works fine without error.
I debugged a lot but dint find any clue for this. Any help will be very helpful for me.
Thanks
Add String arguments to setProd and setSchema as you have already done with setMfr:
public void setProd(String prod) {
^ ^
and
public void setSchema(String sche) {
^ ^
setSchema() receives no parameters in your declaration. Change it to:
public void setSchema(String sche) {
this.sche = sche;
}
Same holds true for setProd
If you use any IDE, I advise you:
look into the warnings that you will get (the assignment this.sche = sche will give warning The assignment to variable thing has no effect in case of no argument method).
Generate the setters/getters automatically, don't code them by yourself (thus avoiding any possible typing mistakes). E.g. in Eclipse that will be alt+shift+s, then r
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>