diff --git a/src/main/java/com/solab/iso8583/IsoMessage.java b/src/main/java/com/solab/iso8583/IsoMessage.java index 90c3d89..acefbea 100644 --- a/src/main/java/com/solab/iso8583/IsoMessage.java +++ b/src/main/java/com/solab/iso8583/IsoMessage.java @@ -48,6 +48,7 @@ public class IsoMessage { private int etx = -1; /** Flag to enforce secondary bitmap even if empty. */ private boolean forceb2; + private String encoding = System.getProperty("file.encoding"); /** Creates a new empty message with no values set. */ public IsoMessage() { @@ -66,6 +67,13 @@ public class IsoMessage { return forceb2; } + public void setCharacterEncoding(String value) { + encoding = value; + } + public String getCharacterEncoding() { + return encoding; + } + /** Sets the string to be sent as ISO header, that is, after the length header but before the message type. * This is useful in case an application needs some custom data in the ISO header of each message (very rare). */ public void setIsoHeader(String value) { @@ -119,6 +127,7 @@ public class IsoMessage { if (index < 2 || index > 128) { throw new IndexOutOfBoundsException("Field index must be between 2 and 128"); } + field.setCharacterEncoding(encoding); fields[index] = field; } @@ -153,6 +162,7 @@ public class IsoMessage { } else { v = new IsoValue(t, value, encoder); } + v.setCharacterEncoding(encoding); fields[index] = v; } } diff --git a/src/main/java/com/solab/iso8583/IsoValue.java b/src/main/java/com/solab/iso8583/IsoValue.java index 595fd8d..8c0ffe8 100644 --- a/src/main/java/com/solab/iso8583/IsoValue.java +++ b/src/main/java/com/solab/iso8583/IsoValue.java @@ -40,6 +40,7 @@ public class IsoValue implements Cloneable { private T value; private CustomField encoder; private int length; + private String encoding; public IsoValue(IsoType t, T value) { this(t, value, null); @@ -156,6 +157,13 @@ public class IsoValue implements Cloneable { return value; } + public void setCharacterEncoding(String value) { + encoding = value; + } + public String getCharacterEncoding() { + return encoding; + } + /** Returns the formatted value as a String. The formatting depends on the type of the * receiver. */ public String toString() { @@ -302,8 +310,7 @@ public class IsoValue implements Cloneable { } } } else { - //Just write the value as text - outs.write(toString().getBytes()); + outs.write(encoding == null ? toString().getBytes() : toString().getBytes(encoding)); } } diff --git a/src/main/java/com/solab/iso8583/MessageFactory.java b/src/main/java/com/solab/iso8583/MessageFactory.java index ed94a44..950fd71 100644 --- a/src/main/java/com/solab/iso8583/MessageFactory.java +++ b/src/main/java/com/solab/iso8583/MessageFactory.java @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA package com.solab.iso8583; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.util.ArrayList; import java.util.BitSet; @@ -72,6 +73,25 @@ public class MessageFactory { /** Flag to specify if missing fields should be ignored as long as they're at the end of the message. */ private boolean ignoreLast; private boolean forceb2; + private String encoding = System.getProperty("file.encoding"); + + /** Sets the character encoding used for parsing ALPHA, LLVAR and LLLVAR fields. */ + public void setCharacterEncoding(String value) { + encoding = value; + if (parseMap.size() > 0) { + for (Map pt : parseMap.values()) { + for (FieldParseInfo fpi : pt.values()) { + fpi.setCharacterEncoding(encoding); + } + } + } + } + + /** Returns the encoding used to parse ALPHA, LLVAR and LLLVAR fields. The default is the file.encoding + * system property. */ + public String getCharacterEncoding() { + return encoding; + } /** Sets or clears the flag to pass to new messages, to include a secondary bitmap even if it's not needed. */ public void setForceSecondaryBitmap(boolean flag) { @@ -151,6 +171,7 @@ public class MessageFactory { m.setEtx(etx); m.setBinary(useBinary); m.setForceSecondaryBitmap(forceb2); + m.setCharacterEncoding(encoding); //Copy the values from the template IsoMessage templ = typeTemplates.get(type); @@ -176,6 +197,7 @@ public class MessageFactory { * @param request An ISO8583 message with a request type (ending in 00). */ public IsoMessage createResponse(IsoMessage request) { IsoMessage resp = new IsoMessage(isoHeaders.get(request.getType() + 16)); + resp.setCharacterEncoding(request.getCharacterEncoding()); resp.setBinary(request.isBinary()); resp.setType(request.getType() + 16); resp.setEtx(etx); @@ -206,9 +228,10 @@ public class MessageFactory { * @param buf The byte buffer containing the message. Must not include the length header. * @param isoHeaderLength The expected length of the ISO header, after which the message type * and the rest of the message must come. */ - public IsoMessage parseMessage(byte[] buf, int isoHeaderLength) throws ParseException { + public IsoMessage parseMessage(byte[] buf, int isoHeaderLength) + throws ParseException, UnsupportedEncodingException { IsoMessage m = new IsoMessage(isoHeaderLength > 0 ? new String(buf, 0, isoHeaderLength) : null); - //TODO Not really sure if binary support really works, unit tests pending... + m.setCharacterEncoding(encoding); int type = 0; if (useBinary) { type = ((buf[isoHeaderLength] & 0xff) << 8) | (buf[isoHeaderLength + 1] & 0xff); @@ -351,11 +374,8 @@ public class MessageFactory { } else { IsoValue val = fpi.parse(buf, pos, getCustomField(i)); m.setField(i, val); - pos += val.getLength(); - if (val.getType() == IsoType.LLBIN || val.getType() == IsoType.LLLBIN || val.getType() == IsoType.BINARY) { - //Binary types in ASCII are twice as long as they say they are (because of the hex encoding) - pos += val.getLength(); - } + //To get the correct next position, we need to get the number of bytes, not chars + pos += val.toString().getBytes(fpi.getCharacterEncoding()).length; if (val.getType() == IsoType.LLVAR || val.getType() == IsoType.LLBIN) { pos += 2; } else if (val.getType() == IsoType.LLLVAR || val.getType() == IsoType.LLLBIN) { diff --git a/src/main/java/com/solab/iso8583/parse/AlphaNumericFieldParseInfo.java b/src/main/java/com/solab/iso8583/parse/AlphaNumericFieldParseInfo.java index 648b22a..8fc92b5 100644 --- a/src/main/java/com/solab/iso8583/parse/AlphaNumericFieldParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/AlphaNumericFieldParseInfo.java @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package com.solab.iso8583.parse; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import com.solab.iso8583.CustomField; @@ -34,7 +35,7 @@ public abstract class AlphaNumericFieldParseInfo extends FieldParseInfo { super(t, len); } - public IsoValue parse(byte[] buf, int pos, CustomField custom) throws ParseException { + public IsoValue parse(byte[] buf, int pos, CustomField custom) throws ParseException, UnsupportedEncodingException { if (pos < 0) { throw new ParseException(String.format("Invalid position %d", pos), pos); } @@ -42,12 +43,16 @@ public abstract class AlphaNumericFieldParseInfo extends FieldParseInfo { throw new ParseException(String.format("Insufficient data for %s field of length %d, pos %d", type, length, pos), pos); } + String _v = new String(buf, pos, length, getCharacterEncoding()); + if (_v.length() != length) { + _v = new String(buf, pos, buf.length-pos, getCharacterEncoding()).substring(0, length); + } if (custom == null) { - return new IsoValue(type, new String(buf, pos, length), length, null); + return new IsoValue(type, _v, length, null); } else { - IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos, length)), length, custom); + IsoValue v = new IsoValue(type, custom.decodeField(_v), length, custom); if (v.getValue() == null) { - return new IsoValue(type, new String(buf, pos, length), length, null); + return new IsoValue(type, _v, length, null); } return v; } diff --git a/src/main/java/com/solab/iso8583/parse/AlphaParseInfo.java b/src/main/java/com/solab/iso8583/parse/AlphaParseInfo.java index d19cc6b..1887cb5 100644 --- a/src/main/java/com/solab/iso8583/parse/AlphaParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/AlphaParseInfo.java @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package com.solab.iso8583.parse; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import com.solab.iso8583.CustomField; @@ -34,13 +35,14 @@ public class AlphaParseInfo extends AlphaNumericFieldParseInfo { super(IsoType.ALPHA, len); } - public IsoValue parseBinary(byte[] buf, int pos, CustomField custom) throws ParseException { + public IsoValue parseBinary(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException { if (custom == null) { - return new IsoValue(type, new String(buf, pos, length), length, null); + return new IsoValue(type, new String(buf, pos, length, getCharacterEncoding()), length, null); } else { - IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos, length)), length, custom); + IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos, length, getCharacterEncoding())), length, custom); if (v.getValue() == null) { - return new IsoValue(type, new String(buf, pos, length), length, null); + return new IsoValue(type, new String(buf, pos, length, getCharacterEncoding()), length, null); } return v; } diff --git a/src/main/java/com/solab/iso8583/parse/BinaryParseInfo.java b/src/main/java/com/solab/iso8583/parse/BinaryParseInfo.java index 06fb9ce..71590f6 100644 --- a/src/main/java/com/solab/iso8583/parse/BinaryParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/BinaryParseInfo.java @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package com.solab.iso8583.parse; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import com.solab.iso8583.CustomField; @@ -38,7 +39,7 @@ public class BinaryParseInfo extends FieldParseInfo { @Override public IsoValue parse(byte[] buf, int pos, CustomField custom) - throws ParseException { + throws ParseException, UnsupportedEncodingException { if (pos < 0) { throw new ParseException(String.format("Invalid position %d", pos), pos); } @@ -50,7 +51,7 @@ public class BinaryParseInfo extends FieldParseInfo { if (custom == null) { return new IsoValue(type, binval, binval.length, null); } else { - IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos, length*2)), length, custom); + IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos, length*2, getCharacterEncoding())), length, custom); if (v.getValue() == null) { return new IsoValue(type, binval, binval.length, null); } diff --git a/src/main/java/com/solab/iso8583/parse/ConfigParser.java b/src/main/java/com/solab/iso8583/parse/ConfigParser.java index b03df89..7ab4b9a 100644 --- a/src/main/java/com/solab/iso8583/parse/ConfigParser.java +++ b/src/main/java/com/solab/iso8583/parse/ConfigParser.java @@ -139,6 +139,7 @@ public class ConfigParser { NodeList fields = elem.getElementsByTagName("field"); IsoMessage m = new IsoMessage(); m.setType(type); + m.setCharacterEncoding(mfact.getCharacterEncoding()); for (int j = 0; j < fields.getLength(); j++) { Element f = (Element)fields.item(j); int num = Integer.parseInt(f.getAttribute("num")); @@ -172,7 +173,7 @@ public class ConfigParser { if (f.getAttribute("length").length() > 0) { length = Integer.parseInt(f.getAttribute("length")); } - parseMap.put(num, FieldParseInfo.getInstance(itype, length)); + parseMap.put(num, FieldParseInfo.getInstance(itype, length, mfact.getCharacterEncoding())); } mfact.setParseMap(type, parseMap); } @@ -189,6 +190,17 @@ public class ConfigParser { } } + /** This method attempts to open a stream from the XML configuration in the specified URL and + * configure the message factory from that config. */ + public static void configureFromUrl(MessageFactory mfact, URL url) throws IOException { + InputStream stream = url.openStream(); + try { + parse(mfact, stream); + } finally { + stream.close(); + } + } + /** Configures a MessageFactory using the configuration file at the path specified (will be searched * within the classpath using the MessageFactory's ClassLoader). This is useful for configuring * Spring-bound instances of MessageFactory for example. */ diff --git a/src/main/java/com/solab/iso8583/parse/FieldParseInfo.java b/src/main/java/com/solab/iso8583/parse/FieldParseInfo.java index 0859d39..68e078e 100644 --- a/src/main/java/com/solab/iso8583/parse/FieldParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/FieldParseInfo.java @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package com.solab.iso8583.parse; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import com.solab.iso8583.CustomField; @@ -32,6 +33,7 @@ public abstract class FieldParseInfo { protected IsoType type; protected int length; + private String encoding = System.getProperty("file.encoding"); /** Creates a new instance that parses a value of the specified type, with the specified length. * The length is only useful for ALPHA and NUMERIC types. @@ -45,6 +47,13 @@ public abstract class FieldParseInfo { length = len; } + public void setCharacterEncoding(String value) { + encoding = value; + } + public String getCharacterEncoding() { + return encoding; + } + /** Returns the specified length for the data to be parsed. */ public int getLength() { return length; @@ -57,40 +66,47 @@ public abstract class FieldParseInfo { /** Parses the character data from the buffer and returns the * IsoValue with the correct data type in it. */ - public abstract IsoValue parse(byte[] buf, int pos, CustomField custom) throws ParseException; + public abstract IsoValue parse(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException; /** Parses binary data from the buffer, creating and returning an IsoValue of the configured * type and length. */ - public abstract IsoValue parseBinary(byte[] buf, int pos, CustomField custom) throws ParseException; + public abstract IsoValue parseBinary(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException; /** Returns a new FieldParseInfo instance that can parse the specified type. */ - public static FieldParseInfo getInstance(IsoType t, int len) { + public static FieldParseInfo getInstance(IsoType t, int len, String encoding) { + FieldParseInfo fpi = null; if (t == IsoType.ALPHA) { - return new AlphaParseInfo(len); + fpi = new AlphaParseInfo(len); } else if (t == IsoType.AMOUNT) { - return new AmountParseInfo(); + fpi = new AmountParseInfo(); } else if (t == IsoType.BINARY) { - return new BinaryParseInfo(len); + fpi = new BinaryParseInfo(len); } else if (t == IsoType.DATE10) { - return new Date10ParseInfo(); + fpi = new Date10ParseInfo(); } else if (t == IsoType.DATE4) { - return new Date4ParseInfo(); + fpi = new Date4ParseInfo(); } else if (t == IsoType.DATE_EXP) { - return new DateExpParseInfo(); + fpi = new DateExpParseInfo(); } else if (t == IsoType.LLBIN) { - return new LlbinParseInfo(); + fpi = new LlbinParseInfo(); } else if (t == IsoType.LLLBIN) { - return new LllbinParseInfo(); + fpi = new LllbinParseInfo(); } else if (t == IsoType.LLLVAR) { - return new LllvarParseInfo(); + fpi = new LllvarParseInfo(); } else if (t == IsoType.LLVAR) { - return new LlvarParseInfo(); + fpi = new LlvarParseInfo(); } else if (t == IsoType.NUMERIC) { - return new NumericParseInfo(len); + fpi = new NumericParseInfo(len); } else if (t == IsoType.TIME) { - return new TimeParseInfo(); + fpi = new TimeParseInfo(); } - throw new IllegalArgumentException(String.format("Cannot parse type %s", t)); + if (fpi == null) { + throw new IllegalArgumentException(String.format("Cannot parse type %s", t)); + } + fpi.setCharacterEncoding(encoding); + return fpi; } } diff --git a/src/main/java/com/solab/iso8583/parse/LlbinParseInfo.java b/src/main/java/com/solab/iso8583/parse/LlbinParseInfo.java index ca4f2be..5eab1be 100644 --- a/src/main/java/com/solab/iso8583/parse/LlbinParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/LlbinParseInfo.java @@ -47,7 +47,7 @@ public class LlbinParseInfo extends FieldParseInfo { throw new ParseException(String.format("Invalid LLBIN length %d pos %d", length, pos), pos); } if (pos+2 > buf.length || length+pos+2 > buf.length) { - throw new ParseException(String.format("Insufficient data for LLBIN field, pos %d", pos), pos); + throw new ParseException(String.format("Insufficient data for LLBIN field, pos %d (LEN states '%s')", pos, new String(buf, pos, 2)), pos); } byte[] binval = length == 0 ? new byte[0] : HexCodec.hexDecode(new String(buf, pos + 2, length)); if (custom == null) { diff --git a/src/main/java/com/solab/iso8583/parse/LllvarParseInfo.java b/src/main/java/com/solab/iso8583/parse/LllvarParseInfo.java index 367e4a1..2026fcf 100644 --- a/src/main/java/com/solab/iso8583/parse/LllvarParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/LllvarParseInfo.java @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package com.solab.iso8583.parse; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import com.solab.iso8583.CustomField; @@ -35,7 +36,8 @@ public class LllvarParseInfo extends FieldParseInfo { super(IsoType.LLLVAR, 0); } - public IsoValue parse(byte[] buf, int pos, CustomField custom) throws ParseException { + public IsoValue parse(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException { if (pos < 0) { throw new ParseException(String.format("Invalid position %d", pos), pos); } @@ -50,7 +52,13 @@ public class LllvarParseInfo extends FieldParseInfo { if (length+pos+3 > buf.length) { throw new ParseException(String.format("Insufficient data for LLLVAR field, pos %d", pos), pos); } - String _v = length == 0 ? "" : new String(buf, pos + 3, length); + String _v = length == 0 ? "" : new String(buf, pos + 3, length, getCharacterEncoding()); + //This is new: if the String's length is different from the specified length in the buffer, + //there are probably some extended characters. So we create a String from the rest of the buffer, + //and then cut it to the specified length. + if (_v.length() != length) { + _v = new String(buf, pos + 3, buf.length-pos-3, getCharacterEncoding()).substring(0, length); + } if (custom == null) { return new IsoValue(type, _v, length, null); } else { @@ -63,7 +71,8 @@ public class LllvarParseInfo extends FieldParseInfo { } } - public IsoValue parseBinary(byte[] buf, int pos, CustomField custom) throws ParseException { + public IsoValue parseBinary(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException { length = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f); if (length < 0) { throw new ParseException(String.format("Invalid LLLVAR length %d pos %d", length, pos), pos); @@ -72,11 +81,11 @@ public class LllvarParseInfo extends FieldParseInfo { throw new ParseException(String.format("Insufficient data for LLLVAR field, pos %d", pos), pos); } if (custom == null) { - return new IsoValue(type, new String(buf, pos + 2, length), null); + return new IsoValue(type, new String(buf, pos + 2, length, getCharacterEncoding()), null); } else { - IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos + 2, length)), custom); + IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos + 2, length, getCharacterEncoding())), custom); if (v.getValue() == null) { - return new IsoValue(type, new String(buf, pos + 2, length), null); + return new IsoValue(type, new String(buf, pos + 2, length, getCharacterEncoding()), null); } return v; } diff --git a/src/main/java/com/solab/iso8583/parse/LlvarParseInfo.java b/src/main/java/com/solab/iso8583/parse/LlvarParseInfo.java index 21efbba..157863c 100644 --- a/src/main/java/com/solab/iso8583/parse/LlvarParseInfo.java +++ b/src/main/java/com/solab/iso8583/parse/LlvarParseInfo.java @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package com.solab.iso8583.parse; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import com.solab.iso8583.CustomField; @@ -34,7 +35,8 @@ public class LlvarParseInfo extends FieldParseInfo { super(IsoType.LLVAR, 0); } - public IsoValue parse(byte[] buf, int pos, CustomField custom) throws ParseException { + public IsoValue parse(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException { if (pos < 0) { throw new ParseException(String.format("Invalid position %d", pos), pos); } @@ -45,7 +47,13 @@ public class LlvarParseInfo extends FieldParseInfo { if (pos+2 > buf.length || length+pos+2 > buf.length) { throw new ParseException(String.format("Insufficient data for LLVAR field, pos %d", pos), pos); } - String _v = length == 0 ? "" : new String(buf, pos + 2, length); + String _v = length == 0 ? "" : new String(buf, pos + 2, length, getCharacterEncoding()); + //This is new: if the String's length is different from the specified length in the buffer, + //there are probably some extended characters. So we create a String from the rest of the buffer, + //and then cut it to the specified length. + if (_v.length() != length) { + _v = new String(buf, pos + 2, buf.length-pos-2, getCharacterEncoding()).substring(0, length); + } if (custom == null) { return new IsoValue(type, _v, length, null); } else { @@ -57,7 +65,8 @@ public class LlvarParseInfo extends FieldParseInfo { } } - public IsoValue parseBinary(byte[] buf, int pos, CustomField custom) throws ParseException { + public IsoValue parseBinary(byte[] buf, int pos, CustomField custom) + throws ParseException, UnsupportedEncodingException { length = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f); if (length < 0) { @@ -67,11 +76,11 @@ public class LlvarParseInfo extends FieldParseInfo { throw new ParseException(String.format("Insufficient data for LLVAR field, pos %d", pos), pos); } if (custom == null) { - return new IsoValue(type, new String(buf, pos + 1, length), null); + return new IsoValue(type, new String(buf, pos + 1, length, getCharacterEncoding()), null); } else { - IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos + 1, length)), custom); + IsoValue v = new IsoValue(type, custom.decodeField(new String(buf, pos + 1, length, getCharacterEncoding())), custom); if (v.getValue() == null) { - return new IsoValue(type, new String(buf, pos + 1, length), null); + return new IsoValue(type, new String(buf, pos + 1, length, getCharacterEncoding()), null); } return v; } diff --git a/src/test/java/j8583/TestBinaries.java b/src/test/java/j8583/TestBinaries.java index 803a28d..fe1ba51 100644 --- a/src/test/java/j8583/TestBinaries.java +++ b/src/test/java/j8583/TestBinaries.java @@ -1,6 +1,7 @@ package j8583; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.text.ParseException; import java.util.Arrays; @@ -22,9 +23,11 @@ public class TestBinaries { @Before public void setup() throws IOException { + mfactAscii.setCharacterEncoding("UTF-8"); mfactAscii.setConfigPath("config.xml"); - mfactBin.setConfigPath("config.xml"); mfactAscii.setAssignDate(true); + mfactBin.setCharacterEncoding("UTF-8"); + mfactBin.setConfigPath("config.xml"); mfactBin.setAssignDate(true); mfactBin.setUseBinaryMessages(true); } @@ -61,19 +64,19 @@ public class TestBinaries { } @Test - public void testMessages() throws ParseException { + public void testMessages() throws ParseException, UnsupportedEncodingException { //Create a message with both factories IsoMessage ascii = mfactAscii.newMessage(0x600); IsoMessage bin = mfactBin.newMessage(0x600); //HEXencode the binary message, headers should be similar to the ASCII version String hexBin = HexCodec.hexEncode(bin.writeData()); String hexAscii = new String(ascii.writeData()).toUpperCase(); - System.out.printf("bin: %s%nascii: %s%n", hexBin, hexAscii); Assert.assertEquals("0600", hexBin.substring(0, 4)); //Should be the same up to the field 42 (first 80 chars) Assert.assertEquals(hexAscii.substring(0, 88), hexBin.substring(0, 88)); //Parse both messages - IsoMessage ascii2 = mfactAscii.parseMessage(ascii.writeData(), 0); + byte[] asciiBuf = ascii.writeData(); + IsoMessage ascii2 = mfactAscii.parseMessage(asciiBuf, 0); testParsed(ascii2); Assert.assertEquals(ascii.getObjectValue(7).toString(), ascii2.getObjectValue(7).toString()); IsoMessage bin2 = mfactBin.parseMessage(bin.writeData(), 0); diff --git a/src/test/java/j8583/TestIsoMessage.java b/src/test/java/j8583/TestIsoMessage.java index 6deb2af..649902e 100644 --- a/src/test/java/j8583/TestIsoMessage.java +++ b/src/test/java/j8583/TestIsoMessage.java @@ -1,7 +1,9 @@ package j8583; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.text.ParseException; import org.junit.Assert; @@ -23,6 +25,7 @@ public class TestIsoMessage { @Before public void init() throws IOException { mf = new MessageFactory(); + mf.setCharacterEncoding("UTF-8"); mf.setCustomField(48, new CustomField48()); mf.setConfigPath("config.xml"); } @@ -60,7 +63,7 @@ public class TestIsoMessage { } @Test - public void testEncoding() throws ParseException { + public void testEncoding() throws Exception { IsoMessage m1 = mf.newMessage(0x200); byte[] buf = m1.writeData(); IsoMessage m2 = mf.parseMessage(buf, mf.getIsoHeader(0x200).length()); diff --git a/src/test/resources/config.xml b/src/test/resources/config.xml index 95fd0da..2bb32e0 100644 --- a/src/test/resources/config.xml +++ b/src/test/resources/config.xml @@ -21,7 +21,7 @@ Life, the Universe, and Everything|42 484 B456PRO1+000 - 1234P vamos a meter mas de 90 caracteres en este campo para comprobar si hay algun error en el parseo del mismo. Esta definido como un LLLVAR aqui por lo tanto esto debe caber sin problemas; las guias de parseo de 200 y 210 tienen LLLVAR en campo 61 tambien. + 1234P vamos a meter más de 90 caracteres en este campo para comprobar si hay algun error en el parseo del mismo. Esta definido como un LLLVAR aqui por lo tanto esto debe caber sin problemas; las guias de parseo de 200 y 210 tienen LLLVAR en campo 61 tambien. 999 ABCD diff --git a/src/test/resources/parse1.txt b/src/test/resources/parse1.txt index 639ca31..f4a8fb2 100644 --- a/src/test/resources/parse1.txt +++ b/src/test/resources/parse1.txt @@ -1,2 +1,2 @@ -ISO0250000550210B23A80012EA080180000000014000004650000000000003000042813054746877112594604280428081103123173766123456123456=00123442579114472300614209027600TESTSOLAB TEST-3 DF MX484012B123PRO1+000013 0000P0312304ABCD040ABCD8123477547 +ISO0250000550210B23A80012EA080180000000014000004650000000000003000042813054746877112594604280428081103123173766123456123456=00123442579114472300614209027600TéSTSOLAB áéíóú üñÑ TEST-3 DF MX484012B123P®O1+000013 0000P0312304ABCD040ABCD8123477547