javajspstruts2type-conversioninterceptorstack

Strust2 type conversion error from String to byte array?


Struts 2 has implicit type conversion which take cares of user entered params type cast e.g. int, string , double ,boolean etc. But my requirement is to convert rich text area input to byte array and for that I have created a custom type converter class.

public class StringToByteArrayConverter extends StrutsTypeConverter{

    @Override
    public Object convertFromString(Map context, String[] value, Class arg2) {
        String val = value[0];
        return val.getBytes() ; 
    }

    @Override
    public String convertToString(Map context, Object value) {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream os;
            try {
                os = new ObjectOutputStream(out);
                os.writeObject(value);
                return new String(out.toByteArray());
            } catch (IOException e) {           
                e.printStackTrace();
                return null;                    
            }
    }
}

And in model class I have specified the following annotation on setter of property

@TypeConversion(converter="org.package.name.StringToByteArrayConverter")
public void setVarName(byte[] varName) {
    this.varName = varName;
}

The same annotation is applyed on getter method also. Now everything seems fine I am getting correct data in Action method. But while displaying the data on jsp I am getting some extra symbols with original content.

eg. user input is :what is your name ? it display on jsp : ¬íur[B¬óøTàxpwhat is your name ?

Any one has any Idea, What am I dong wrong ?


Solution

  • Start by specifying the correct Charset in the byte-to-string processing:

    val.getBytes();        // wrong
    val.getBytes("UTF-8"); // right
    

    assuming you're working on UTF-8. Otherwise, just put the charset you're using, but never use val.getBytes(); that will take the platform-default charset, that might differ from your app's charset, creating conversion errors and artifacts like the ones you're getting now.

    Then the ObjectOutputStream doesn't convince me. Try with a simple

    @Override
    public String convertToString(Map context, Object value) {
        try {            
            return new String((byte[]) value, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    

    and eventually add logging for wrong usage, eg: if (value instanceof byte[]).. else LOG.warn....