I am trying to marshal with jaxb an object which contains an Image, and afterwards unmarshalling it (i.e. save/load).
Is there a way to store that image?
I am trying to create a function which returns the byte array describing the swt.image imagedata, but once I marked it as an #XmlElement, the process of storing it fails throwing an Exception like this:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
JAXB annotation is placed on a method that is not a JAXB property
this problem is related to the following location:
at #javax.xml.bind.annotation.XmlElement()
Also, I have tested to convert the SWT.Image to a AWT.BufferedImage, but I still get the same Exception.
Your exception indicates that you have placed an annotation on a method that isn't an accessor (get/set method). Below is an example using a java.awt.Image property:
Root
package forum9094655;
import java.awt.Image;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Root {
private Image image;
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
}
Demo
package forum9094655;
import java.awt.Image;
import java.awt.image.BufferedImage;
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(Root.class);
Root root = new Root();
Image image = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
root.setImage(image);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<image>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mNgYGAAAAAEAAHI6uv5AAAAAElFTkSuQmCC</image>
</root>
Related
I know that request template supports XPath, so that I can get value from request like {{xPath request.body '/outer/inner/text()'}}. I already have a XML file as response, and I want to inject this value I got from request, but keep the other parts of this response XML intact. For example, I want to inject it to XPATH /svc_result/slia/pos/msid.
And I need to use it in standalone mode.
I see another question(Wiremock Stand alone - How to manipulate response with request data) but that was with JSON, I have XML request/response.
How can it be done? Thanks.
For example, I have this definition of mapping:
{
"request": {
"method": "POST",
"bodyPatterns": [
{
"matchesXPath": {
"expression": "/svc_init/slir/msids/msid[#type='MSISDN']/text()",
"equalTo": "200853000105614"
}
},
{
"matchesXPath": "/svc_init/hdr/client[id and pwd]"
}
]
},
"response": {
"status": 200,
"bodyFileName": "slia.xml",
"headers": {
"Content-Type": "application/xml;charset=UTF-8"
}
}
}
And this request:
<?xml version="1.0"?>
<!DOCTYPE svc_init>
<svc_init ver="3.2.0">
<hdr ver="3.2.0">
<client>
<id>dummy</id>
<pwd>dummy</pwd>
</client>
</hdr>
<slir ver="3.2.0" res_type="SYNC">
<msids>
<msid type="MSISDN">200853000105614</msid>
</msids>
</slir>
</svc_init>
I expect this response, with xxxxxxxxxxx replaced with the <msid> in the request.
<?xml version="1.0" ?>
<!DOCTYPE svc_result SYSTEM "MLP_SVC_RESULT_320.DTD">
<svc_result ver="3.2.0">
<slia ver="3.0.0">
<pos>
<msid type="MSISDN" enc="ASC">xxxxxxxxxxx</msid>
<pd>
<time utc_off="+0800">20111122144915</time>
<shape>
<EllipticalArea srsName="www.epsg.org#4326">
<coord>
<X>00 01 01N</X>
<Y>016 31 53E</Y>
</coord>
<angle>0</angle>
<semiMajor>2091</semiMajor>
<semiMinor>2091</semiMinor>
<angularUnit>Degrees</angularUnit>
</EllipticalArea>
</shape>
<lev_conf>90</lev_conf>
</pd>
<gsm_net_param>
<cgi>
<mcc>100</mcc>
<mnc>01</mnc>
<lac>2222</lac>
<cellid>10002</cellid>
</cgi>
<neid>
<vmscid>
<vmscno>00004946000</vmscno>
</vmscid>
<vlrid>
<vlrno>99994946000</vlrno>
</vlrid>
</neid>
</gsm_net_param>
</pos>
</slia>
</svc_result>
My first thought was to use transformerParameters to change the response file by inserting the value from the body. Unfortunately, WireMock doesn't resolve the helpers before inserting them into the body response. So while we can reference that MSID value via an xpath helper like
{{xPath request.body '/svc_init/slir/msids/msid/text()'}}
if we try to insert that as a custom transformer parameter, it won't resolve. (I've written up an issue on the WireMock github about this.)
Unfortunately, I think this leaves us with having to write a custom extension that will take the request and find the value and then modify the response file. More information on creating a custom transformer extensions can be found here.
At last I created my own transformer:
package com.company.department.app.extensions;
import com.github.tomakehurst.wiremock.common.FileSource;
import com.github.tomakehurst.wiremock.extension.Parameters;
import com.github.tomakehurst.wiremock.extension.ResponseTransformer;
import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.http.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
public class NLGResponseTransformer extends ResponseTransformer {
private static final Logger LOG = LoggerFactory.getLogger(NLGResponseTransformer.class);
private static final String SLIA_FILE = "/stubs/__files/slia.xml";
private static final String REQ_IMSI_XPATH = "/svc_init/slir/msids/msid";
private static final String[] RES_IMSI_XPATHS = {
"/svc_result/slia/pos/msid",
"/svc_result/slia/company_mlp320_slia/company_netinfo/company_ms_netinfo/msid"
};
private static final String[] RES_TIME_XPATHS = {
// for slia.xml
"/svc_result/slia/company_mlp320_slia/company_netinfo/company_ms_netinfo/time",
// for slia_poserror.xml
"/svc_result/slia/pos/poserror/time"
};
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
private static final String UTC_OFF = "utc_off";
private static final String TRANSFORM_FACTORY_ATTRIBUTE_INDENT_NUMBER = "indent-number";
protected static final String COMPANY_MLP_320_SLIA_EXTENSION_DTD = "company_mlp320_slia_extension.dtd";
protected static final String MLP_SVC_RESULT_320_DTD = "MLP_SVC_RESULT_320.DTD";
#Override
public String getName() {
return "inject-request-values";
}
#Override
public Response transform(Request request, Response response, FileSource fileSource, Parameters parameters) {
Document responseDocument = injectValuesFromRequest(request);
String transformedResponse = transformToString(responseDocument);
if (transformedResponse == null) {
return response;
}
return Response.Builder.like(response)
.but()
.body(transformedResponse)
.build();
}
private Document injectValuesFromRequest(Request request) {
// NOTE: according to quickscan:
// "time" element in the MLP is the time MME reports cell_id to GMLC (NLG), NOT the time when MME got the cell_id.
LocalDateTime now = LocalDateTime.now();
Document responseTemplate = readDocument(SLIA_FILE);
Document requestDocument = readDocumentFromBytes(request.getBody());
if (responseTemplate == null || requestDocument == null) {
return null;
}
try {
injectIMSI(responseTemplate, requestDocument);
injectTime(responseTemplate, now);
} catch (XPathExpressionException e) {
LOG.error("Cannot parse XPath expression {}. Cause: ", REQ_IMSI_XPATH, e);
}
return responseTemplate;
}
private Document readDocument(String inputStreamPath) {
try {
DocumentBuilder builder = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
// ignore missing dtd
builder.setEntityResolver((publicId, systemId) -> {
if (systemId.contains(COMPANY_MLP_320_SLIA_EXTENSION_DTD) ||
systemId.contains(MLP_SVC_RESULT_320_DTD)) {
return new InputSource(new StringReader(""));
} else {
return null;
}
});
return builder.parse(this.getClass().getResourceAsStream(inputStreamPath));
} catch (Exception e) {
LOG.error("Cannot construct document from resource path. ", e);
return null;
}
}
private Document readDocumentFromBytes(byte[] array) {
try {
DocumentBuilder builder = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
// ignore missing dtd
builder.setEntityResolver((publicId, systemId) -> {
if (systemId.contains(COMPANY_MLP_320_SLIA_EXTENSION_DTD) ||
systemId.contains(MLP_SVC_RESULT_320_DTD)) {
return new InputSource(new StringReader(""));
} else {
return null;
}
});
return builder.parse(new ByteArrayInputStream(array));
} catch (Exception e) {
LOG.error("Cannot construct document from byte array. ", e);
return null;
}
}
private XPath newXPath() {
return XPathFactory.newInstance().newXPath();
}
private void injectTime(Document responseTemplate, LocalDateTime now) throws XPathExpressionException {
for (String timeXPath: RES_TIME_XPATHS) {
Node timeTarget = (Node) (newXPath().evaluate(timeXPath, responseTemplate, XPathConstants.NODE));
if (timeTarget != null) {
// set offset in attribute
Node offset = timeTarget.getAttributes().getNamedItem(UTC_OFF);
offset.setNodeValue(getOffsetString());
// set value
timeTarget.setTextContent(TIME_FORMAT.format(now));
}
}
}
private void injectIMSI(Document responseTemplate, Document requestDocument) throws XPathExpressionException {
Node imsiSource = (Node) (newXPath().evaluate(REQ_IMSI_XPATH, requestDocument, XPathConstants.NODE));
String imsi = imsiSource.getTextContent();
for (String xpath : RES_IMSI_XPATHS) {
Node imsiTarget = (Node) (newXPath().evaluate(xpath, responseTemplate, XPathConstants.NODE));
if (imsiTarget != null) {
imsiTarget.setTextContent(imsi);
}
}
}
private String transformToString(Document document) {
if (document == null) {
return null;
}
document.setXmlStandalone(true); // make document to be standalone, so we can avoid outputing standalone="no" in first line
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans;
try {
trans = tf.newTransformer();
trans.setOutputProperty(OutputKeys.INDENT, "no"); // no extra indent; file already has intent of 4
// cannot find a workaround to inject dtd in doctype line. TODO
//trans.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "MLP_SVC_RESULT_320.DTD [<!ENTITY % extension SYSTEM \"company_mlp320_slia_extension.dtd\"> %extension;]");
StringWriter sw = new StringWriter();
trans.transform(new DOMSource(document), new StreamResult(sw));
// Spaces between tags are considered as text node, so when outputing we need to remove the extra empty lines
return sw.toString().replaceAll("\\n\\s*\\n", "\n");
} catch (TransformerException e) {
LOG.error("Cannot transform response document to String. ", e);
return null;
}
}
/**
* Compare system default timezone with UTC and get zone offset in form of (+/-)XXXX.
* Dependent on the machine default timezone/locale.
* #return
*/
private String getOffsetString() {
// getting offset in (+/-)XX:XX format, or "Z" if is UTC
String offset = ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()).getOffset().toString();
if (offset.equals("Z")) {
return "+0000";
}
return offset.replace(":", "");
}
}
And use it like this:
mvn package it as a JAR(non-runnable), put it aside wiremock standalone jar, for example libs
Run this:
java -cp libs/* com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --extensions com.company.department.app.extensions NLGResponseTransformer --https-port 8443 --verbose
Put the whole command on the same line.
Notice the app jar which contains this transformer and wiremock standalone jar should be among classpath. Also, other dependencies under libs are needed. (I use jib maven plugin which copies all dependencies under libs/; I also move app and wiremock jars to libs/, so I can put "-cp libs/*"). If that does not work, try to specify the location of these two jars in -cp. Be ware that Wiremock will runs OK even when the extension class is not found. So maybe add some loggings.
You can use --root-dir to point to stubs files root, for example --root-dir resources/stubs in my case. By default it points to .(where java runs).
I have a thymeleaf (3.0.11.RELEASE) TEXT template with iteration as follows:
[# th:each="sei : ${specificInfoElements}"]
[(${sei?.elementLabel})] : [(${sei?.elementValues})]
[/]
The above is not getting evaluated by template engine and its coming as follows in output:
[# th:each="sei : ${specificInfoElements}"]
:
[/]
Can anybody help me understand what I am doing wrong?
Note: I am using spring boot.
#Autowired
private SpringTemplateEngine thymeleafTemplateEngine;
Context thymeleafContext = new Context();
thymeleafContext.setVariables(templateModel);
String outputText = thymeleafTemplateEngine.process(emailTemplateString,
thymeleafContext);
I just tested this with Spring Boot and it works fine. What I did exactly:
Create a new project via start.spring.io using Spring Boot 2.5.1 with Java 11
Update application.properties with:
spring.thymeleaf.mode=TEXT
spring.thymeleaf.suffix=.txt
Create a file src/main/resources/templates/test.txt containing the template:
[# th:each="sei : ${specificInfoElements}"]
[(${sei?.elementLabel})] : [(${sei?.elementValues})]
[/]
Create a test class that extends from CommandLineRunner so I can just start the app and see some output:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import java.util.List;
#Component
public class Test implements CommandLineRunner {
#Autowired
private SpringTemplateEngine templateEngine;
#Override
public void run(String... args) throws Exception {
Context context = new Context();
context.setVariable("specificInfoElements", List.of(new SpecificInfoElement("first label", "first value"),
new SpecificInfoElement("second label", "second element")));
String result = templateEngine.process("test", context);
System.out.println("result = " + result);
}
private static class SpecificInfoElement {
private String elementLabel;
private String elementValues;
public SpecificInfoElement(String elementLabel, String elementValues) {
this.elementLabel = elementLabel;
this.elementValues = elementValues;
}
public String getElementLabel() {
return elementLabel;
}
public String getElementValues() {
return elementValues;
}
}
}
Running this outputs:
2021-06-22 08:22:39.229 INFO 13464 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.119 seconds (JVM running for 2.828)
result =
first label : first value
second label : second element
I hope this can help you figure out what you are doing differently.
Since I am storing templates in DB, thymeleaf is using StringTemplateResolver by default. StringTemplateResolver is added to the SpringTemplateEngine upon calling process method for the first time as shown in the code snippet taken from org.thymeleaf.TemplateEngine:
if (this.templateResolvers.isEmpty()) {
this.templateResolvers.add(new StringTemplateResolver());
}
I changed the template mode of StringTemplateResolver before calling the process method as follows:
if (CollectionUtils.isEmpty(springTemplateEngine.getTemplateResolvers())) {
// calling process method will initialize SpringTemplateEngine with StringTemplateResolver.
springTemplateEngine.process("template contents", context);
Set<ITemplateResolver> templateResolvers =
springTemplateEngine.getTemplateResolvers();
StringTemplateResolver stringTemplateResolver = (StringTemplateResolver) templateResolvers.iterator().next();
stringTemplateResolver.setTemplateMode(TemplateMode.TEXT);
}
I am new to "smooks and freemarker".I want access elements in xml document.I am getting this exception while acessing xml element.I am sending my code.
Exception:-
------------
For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this evaluated to a sequence+hash (wrapper: f.e.dom.NodeListModel):
==> employee["first_name"] [in template "free-marker-template" at line 1, column 84]
----
Tip: This XML query result can't be used as string because for that it had to contain exactly 1 XML node, but it contains 0 nodes. That is, the constructing XML query has found no matches.
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${employee["first_name"]} [in template "free-marker-template" at line 1, column 82]
----
Java stack trace (for programmers):
----
freemarker.core.NonStringException: [... Exception message was already printed; see it above ...]
at freemarker.core.EvalUtil.coerceModelToString(EvalUtil.java:381)
at freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
at freemarker.core.DollarVariable.accept(DollarVariable.java:40)
at freemarker.core.Environment.visit(Environment.java:312)
The following are versions
java version : "1.7.0_45"
freemarker : 2.3.22
smooks : 1.6
javacode:-
-----------
package test;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.milyn.Smooks;
import org.milyn.SmooksException;
import org.milyn.container.ExecutionContext;
import org.milyn.event.report.HtmlReportGenerator;
import org.milyn.io.StreamUtils;
import org.milyn.payload.StringResult;
import org.xml.sax.SAXException;
public class SmooksExample {
public SmooksExample() {
// TODO Auto-generated constructor stub
}
protected static void runSmooksNew() throws IOException, SAXException, SmooksException {
try {
Long stTime = System.currentTimeMillis();
System.out.println(stTime + "==" + new Date());
Writer xmlResultWriter = new BufferedWriter(new FileWriter(new File("C:\\Files\\SmookExample\\output_sax.dat")));
transCustomerCSV(new File("C:\\Files\\emp_namespace.xml"), xmlResultWriter);
Long edTime = System.currentTimeMillis();
System.out.println(edTime + "==" + (edTime-stTime) + "===="+ new Date());
String times = String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(edTime-stTime),
TimeUnit.MILLISECONDS.toSeconds(edTime-stTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(edTime-stTime))
);
System.out.println(times);
} finally {
//smooks.close();
}
}
public static void transCustomerCSV(File csvSourceReader, Writer xmlResultWriter) throws IOException, SAXException {
File f = new File("C:/TEMPLATES/smooks-config.xml");
URI u = f.toURI();
Smooks smooks = new Smooks(u.getPath());
ExecutionContext ec = smooks.createExecutionContext();
smooks.filterSource(ec, new StreamSource(csvSourceReader), new StreamResult(xmlResultWriter));
}
/**
* #param args
*/
public static void main(String[] args) throws IOException, SAXException, SmooksException {
System.out.println("\n\n");
System.out.println("==============Message In==============");
SmooksExample.runSmooksNew();
System.out.println("======================================\n");
}
}
Smooks-config.xml
--------------------
<smooks-resource-list xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:core="http://www.milyn.org/xsd/smooks/smooks-core-1.3.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd" xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<params>
<param name="stream.filter.type">SAX</param>
<param name="default.serialization.on">false</param>
</params>
<core:namespaces>
<core:namespace prefix="empl" uri="http://www.example.com/employees"/>
</core:namespaces>
<resource-config selector="employee,first_name">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
<ftl:freemarker applyOnElement="first_name">
<ftl:template><!--<#ftl ns_prefixes={"empl":"http://www.example.com/employees"}>${employee["#id"]},${employee["first_name"]}-->
</ftl:template>
</ftl:freemarker>
</smooks-resource-list>
sample data xml file name: emp_namespace.xml:-
--------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<empl:employees xmlns:empl="http://www.example.com/employees">
<empl:employee id="1">
<empl:first_name>Bill</empl:first_name>
<empl:last_name>Adams</empl:last_name>
<empl:age>25</empl:age>
<empl:hire_date>12-06-1995</empl:hire_date>
<empl:title>Java programmer</empl:title>
<empl:DateCreated>
<empl:Year>1980</empl:Year>
<empl:Month>01</empl:Month>
<empl:Day>01</empl:Day>
</empl:DateCreated>
<empl:DateCompleted>
<empl:Year>1981</empl:Year>
<empl:Month>02</empl:Month>
<empl:Day>02</empl:Day>
</empl:DateCompleted>
</empl:employee>
<empl:employee id="2">
<empl:first_name>Mary</empl:first_name>
<empl:last_name>Jones</empl:last_name>
<empl:age>32</empl:age>
<empl:hire_date>22-09-2001</empl:hire_date>
<empl:title>Sales manager</empl:title>
<empl:DateCreated>
<empl:Year>1982</empl:Year>
<empl:Month>03</empl:Month>
<empl:Day>03</empl:Day>
</empl:DateCreated>
<empl:DateCompleted>
<empl:Year>1983</empl:Year>
<empl:Month>04</empl:Month>
<empl:Day>04</empl:Day>
</empl:DateCompleted>
</empl:employee>
</empl:employees>
In ns_prefixes you specify the namespace prefixes used in the FTL, which is independent of the namespace prefixes used in the XML. FreeMarker doesn't care what the actual prefix was in the XML, it only cares about the namespace URL. So since you have declared the empl prefix, you had to use it the FTL too (like empl\:employee.empl\:first_name - kind of awkward, as the : has to be escaped). But since you mostly access that single namespace, I recommend declaring that namespace URL to be the default:
<#ftl ns_prefixes={"D": "http://www.example.com/employees"}>
And then you don't have to add a prefix:
${employee.first_name}
(Note that here I assume that in Smooks the data-model root is the document element. I don't know if that's true, but anyway, as far as XML namespaces are concerned, this is how it works. Also, you have multiple employee-s in the XML so that above won't work because of multiple matches, but that's another topic.)
I use the below code to get unmarshall and query the unmarshelled object by Xpath.
I am able to get the object after unmarshalling, but while querying by XPath, the value is coming as null.
Do I need to specify any NameSpaceResolver?
Please let me know if you are looking for any further information.
My code:
JAXBContext jaxbContext = (JAXBContext) JAXBContextFactory.createContext(new Class[] {Transaction.class}, null);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StreamSource streamSource= new StreamSource(new StringReader(transactionXML));
transaction = unmarshaller.unmarshal(streamSource, Transaction.class).getValue();
String displayValue = jaxbContext.getValueByXPath(transaction, xPath, null, String.class);
My XML:
<Transaction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<SendingCustomer firstName="test">
</SendingCustomer>
</Transaction>
Since there are no namespaces in your example you do not need to worry about leveraging a NamespaceResolver. You didn't provide the XPath that you were having trouble with, so I have just picked one in the example below.
JAVA MODEL
Transaction
import javax.xml.bind.annotation.*;
#XmlRootElement(name="Transaction")
public class Transaction {
#XmlElement(name="SendingCustomer")
private Customer sendingCustomer;
}
Customer
import javax.xml.bind.annotation.XmlAttribute;
public class Customer {
#XmlAttribute
private String firstName;
#XmlAttribute
private String lastNameDecrypted;
#XmlAttribute(name="OnWUTrustList")
private boolean onWUTrustList;
#XmlAttribute(name="WUTrustListType")
private String wuTrustListType;
}
DEMO CODE
input.xml
<Transaction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SendingCustomer firstName="test" lastNameDecrypted="SMITH"
OnWUTrustList="false" WUTrustListType="NONE">
</SendingCustomer>
</Transaction>
Demo
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jaxbContext = (JAXBContext) JAXBContextFactory.createContext(new Class[] {Transaction.class}, null);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StreamSource streamSource= new StreamSource("src/forum17687460/input.xml");
Transaction transaction = unmarshaller.unmarshal(streamSource, Transaction.class).getValue();
String displayValue = jaxbContext.getValueByXPath(transaction, "SendingCustomer/#firstName", null, String.class);
System.out.println(displayValue);
}
}
Output
test
I've seen this question all over this website. And I've read almost every response. I feel like I'm doing exactly what is required, but I just can't get it to work! I'm trying to package some images into a Runnable Jar so that my program is self-contained. When I run the code in Eclipse, it works as intended. But when I use the executable Jar, the program will not launch. It gives me a NullPointerException on the line where I create the image. The files are in a folder called Resources in the source folder of the project. Here is the code. It is incomplete because this is just a test program that I've been trying to get working.
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class testgui extends JFrame{
private static JLabel label = new JLabel();
private static testgui gui = new testgui();
private static ArrayList<ImageIcon> sprites;
public static void main(String[] args) {
// TODO Auto-generated method stub
sprites = getImages();
BufferedImage backgroundImage;
try {
backgroundImage = ImageIO.read(new testgui().getClass().getClassLoader().getResource("resources/runescapemap.png"));
gui.setContentPane(gui.new ImagePanel(backgroundImage));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
gui.setLayout(new GridLayout(1,2));
label.setIcon(sprites.get(0));
gui.add(label);
gui.setSize(1000,900);
gui.setVisible(true);
}
private static ArrayList<ImageIcon> getImages(){
ImageIcon autoTalkerLogo = new ImageIcon(new testgui().getClass().getClassLoader().getResource("Resources/autotalker-logo.png"));
ImageIcon meterNormal = new ImageIcon(new testgui().getClass().getClassLoader().getResource("Resources/meter.png"));
ImageIcon meterSafe = new ImageIcon(new testgui().getClass().getClassLoader().getResource("Resources/meter-safe.png"));
ImageIcon meterNotSafe = new ImageIcon(new testgui().getClass().getClassLoader().getResource("Resources/meter-notsafe.png"));
ArrayList<ImageIcon> sprites = new ArrayList<ImageIcon>();
sprites.add(autoTalkerLogo);
sprites.add(meterNormal);
sprites.add(meterSafe);
sprites.add(meterNotSafe);
return sprites;
}
class ImagePanel extends JComponent {
private Image backgroundImage;
public ImagePanel(Image image) {
this.backgroundImage = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(backgroundImage, 0, 0, null);
}
}
}
If the folder is genuinely called Resources rather than resources, that could be the problem. While the Windows file system is case-insensitive, jar files aren't.
Try
...getResource("Resources/runescapemap.png")
I note that your later calls to getResource do use Resources rather than resources.
Of course, it could be the other way round - maybe your folder is actually resources, and it's the first call that's okay and the other four should use resources. Either way, it's unlikely that both are correct...