You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Ben <xp...@gmail.com> on 2010/12/09 11:58:39 UTC

CharacterEncoding is overridden by setContentType

Hi there,

I don't get the source code from Tomcat 7.0.5.

In the javadoc it says:
--This method must preserve any response charset that may already have 
--     * been set via a call to response.setContentType(), response.setLocale(),
--     * or response.setCharacterEncoding().

But in the code attahced I cannot see any code related to check if the charset has been set. What's the problem here? Thanks.

PeiSong

    /**
     * Sets the content type.
     *
     * This method must preserve any response charset that may already have 
     * been set via a call to response.setContentType(), response.setLocale(),
     * or response.setCharacterEncoding().
     *
     * @param type the content type
     */
    public void setContentType(String type) {

        int semicolonIndex = -1;

        if (type == null) {
            this.contentType = null;
            return;
        }

        /*
         * Remove the charset param (if any) from the Content-Type, and use it
         * to set the response encoding.
         * The most recent response encoding setting will be appended to the
         * response's Content-Type (as its charset param) by getContentType();
         */
        boolean hasCharset = false;
        int len = type.length();
        int index = type.indexOf(';');
        while (index != -1) {
            semicolonIndex = index;
            index++;
            while (index < len && Character.isSpace(type.charAt(index))) {
                index++;
            }
            if (index+8 < len
                    && type.charAt(index) == 'c'
                    && type.charAt(index+1) == 'h'
                    && type.charAt(index+2) == 'a'
                    && type.charAt(index+3) == 'r'
                    && type.charAt(index+4) == 's'
                    && type.charAt(index+5) == 'e'
                    && type.charAt(index+6) == 't'
                    && type.charAt(index+7) == '=') {
                hasCharset = true;
                break;
            }
            index = type.indexOf(';', index);
        }

        if (!hasCharset) {
            this.contentType = type;
            return;
        }
========NO CHECK AT ALL, means will override even if the charset has been forced to set
        this.contentType = type.substring(0, semicolonIndex);
        String tail = type.substring(index+8);
        int nextParam = tail.indexOf(';');
        String charsetValue = null;
        if (nextParam != -1) {
            this.contentType += tail.substring(nextParam);
            charsetValue = tail.substring(0, nextParam);
        } else {
            charsetValue = tail;
        }

        // The charset value may be quoted, but must not contain any quotes.
        if (charsetValue != null && charsetValue.length() > 0) {
            charsetSet=true;
            charsetValue = charsetValue.replace('"', ' ');
            this.characterEncoding = charsetValue.trim();
        }
    }

Re: CharacterEncoding is overridden by setContentType

Posted by Mark Thomas <ma...@apache.org>.
On 09/12/2010 10:58, Ben wrote:
> Hi there,
> 
> I don't get the source code from Tomcat 7.0.5.
> 
> In the javadoc it says:
> --This method must preserve any response charset that may already have 
> --     * been set via a call to response.setContentType(), response.setLocale(),
> --     * or response.setCharacterEncoding().

If you are going to quote the source code, it is a good idea idea to
mention which class you are quoting. I know the code pretty well and it
still took me a couple of minutes to figure out where you were looking.

> But in the code attahced I cannot see any code related to check if the charset has been set. What's the problem here? Thanks.

The JavaDoc comment means "If setContentType("text/plain") is called
that should not undo a previous call to
setCharacterEncoding("ISO-8859-1"). However, a call to
setContentType("text/plain;charset=UTF-8") *will* overwrite any previous
call to setCharacterEncoding("ISO-8859-1")

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: CharacterEncoding is overridden by setContentType

Posted by Ben <xp...@gmail.com>.
Oh, and I found the force encoding filter does not work if the setContentType is called after. 

Is that becos of this method?


On Dec 9, 2010, at 6:58 PM, Ben wrote:

> Hi there,
> 
> I don't get the source code from Tomcat 7.0.5.
> 
> In the javadoc it says:
> --This method must preserve any response charset that may already have 
> --     * been set via a call to response.setContentType(), response.setLocale(),
> --     * or response.setCharacterEncoding().
> 
> But in the code attahced I cannot see any code related to check if the charset has been set. What's the problem here? Thanks.
> 
> PeiSong
> 
>     /**
>      * Sets the content type.
>      *
>      * This method must preserve any response charset that may already have 
>      * been set via a call to response.setContentType(), response.setLocale(),
>      * or response.setCharacterEncoding().
>      *
>      * @param type the content type
>      */
>     public void setContentType(String type) {
> 
>         int semicolonIndex = -1;
> 
>         if (type == null) {
>             this.contentType = null;
>             return;
>         }
> 
>         /*
>          * Remove the charset param (if any) from the Content-Type, and use it
>          * to set the response encoding.
>          * The most recent response encoding setting will be appended to the
>          * response's Content-Type (as its charset param) by getContentType();
>          */
>         boolean hasCharset = false;
>         int len = type.length();
>         int index = type.indexOf(';');
>         while (index != -1) {
>             semicolonIndex = index;
>             index++;
>             while (index < len && Character.isSpace(type.charAt(index))) {
>                 index++;
>             }
>             if (index+8 < len
>                     && type.charAt(index) == 'c'
>                     && type.charAt(index+1) == 'h'
>                     && type.charAt(index+2) == 'a'
>                     && type.charAt(index+3) == 'r'
>                     && type.charAt(index+4) == 's'
>                     && type.charAt(index+5) == 'e'
>                     && type.charAt(index+6) == 't'
>                     && type.charAt(index+7) == '=') {
>                 hasCharset = true;
>                 break;
>             }
>             index = type.indexOf(';', index);
>         }
> 
>         if (!hasCharset) {
>             this.contentType = type;
>             return;
>         }
> ========NO CHECK AT ALL, means will override even if the charset has been forced to set
>         this.contentType = type.substring(0, semicolonIndex);
>         String tail = type.substring(index+8);
>         int nextParam = tail.indexOf(';');
>         String charsetValue = null;
>         if (nextParam != -1) {
>             this.contentType += tail.substring(nextParam);
>             charsetValue = tail.substring(0, nextParam);
>         } else {
>             charsetValue = tail;
>         }
> 
>         // The charset value may be quoted, but must not contain any quotes.
>         if (charsetValue != null && charsetValue.length() > 0) {
>             charsetSet=true;
>             charsetValue = charsetValue.replace('"', ' ');
>             this.characterEncoding = charsetValue.trim();
>         }
>     }