controller 设置 content-type 问题?

在controller方法里

用getResponse().setHeader("Content-Type", "text/plain;charset=gb2312"); 

或者  renderText(sbResponse.toString(),"text/plain;charset=gb2312");

设置http header 不生效。

但前端跟踪http header 里的 Content-Type 信息还是:Content-Type:text/plain;charset=UTF-8


评论区

JFinal

2019-05-22 10:38

content type 的设置与 setHeader 无关,需要这么来设置:
getResponse().setContentType("text/plain;charset=gb2312");

这种用法在 com.jfinal.render 包下面有大量实例

scocai

2019-05-22 10:45

用 getResponse().setContentType("text/plain;charset=gb2312");
前端跟踪http header 里的 Content-Type 信息还是:Content-Type:text/plain;charset=UTF-8

scocai

2019-05-22 10:52

controller里改变 reader 的CharacterEncoding 应该怎么写?现在调用的都是默认的 UTF-8

JFinal

2019-05-22 11:24

@scocai header 里面的 content type 值,可以用
getResponse().setHeader(...)
或者
getResponse().addHeader(...)

前者会将已经存在的给覆盖,后者是追加

我估计你的用法没生效,是后来有别的地方的代码将你的覆盖掉了,所以你可以改一下 name 来先验证一下,例如 name 改成 jfinal_123:
getResponse().setHeader("jfinal_123", "text/plain;charset=gb2312");

然后先观测这个 jfinal_123 是否成功了,这样就定位到了错误原因

scocai

2019-05-22 11:41

getResponse().setHeader("jfinal_123", "text/plain;charset=gb2312"); 这样写后
头信息是这样的:
Cache-Control:no-cache
Connection:keep-alive
Content-Length:152
Content-Type:text/plain;charset=UTF-8
Date:Wed, 22 May 2019 03:20:24 GMT
Expires:Thu, 01 Jan 1970 00:00:00 GMT
jfinal_123:text/plain;charset=gb2312
Pragma:no-cache
Server:JFinal

scocai

2019-05-22 11:43

但是 getResponse().setHeader("Content-Type", "text/plain;charset=gb2312"); 这样写并没有覆盖原来的Content-Type,还是UTF-8

JFinal

2019-05-22 11:49

@scocai 那是因为别的地方在你这行代码之后被调用,你的在先,人家的在后,所以你的不生效

这个地方可能是 tomcat、jetty、undertow 容器干的,单步调试跟踪一下

scocai

2019-05-22 14:33

从 renderText(sbResponse.toString(),"text/plain;charset=gb2312");
跟踪进去 发现最后执行 public abstract class Render 里 调用了默认的 encoding
private static String encoding = Const.DEFAULT_ENCODING;
renderText 方法里没法改 encoding ,总是调用默认的 常量值。

JFinal

2019-05-22 14:39

@scocai 与之有关的代码是下面两行:
response.setContentType(contentType);
response.setCharacterEncoding(getEncoding());

你传入的 contentType 参数会用上,而后面那个 setCharacterEncoding 仅仅是设置 encoding,应该是不会影响你的 header 中设置的 context type 值的

你可以做一个扩展:
public class MyTextRender extends TextRender {
public void render() {
在这里改掉父类中你认为有问题的代码
}
}

用的时候这样:
render(new MyTextRender(...));

scocai

2019-05-22 14:55

嗯,我就是这么干了,自己写了一个自定义render类,问题解决。感谢波总指导!

JFinal

2019-05-22 14:58

@scocai 看来这个 response.setCharacterEncoding(getEncoding()) 居然影响到了 content type,头一次发现这个

感谢反馈,赞

JFinal

2019-05-30 00:53

jfinal 4.1 已经改进过这个地方,可以直接升级到 4.1,然后删掉你自己的添加的代码:
https://gitee.com/jfinal/jfinal/blob/master/src/main/java/com/jfinal/render/TextRender.java

如下代码所示, setCharacterEncoding 方法调用前判断了 contextType 中是否已经设置过了 charset:
if (ct.indexOf("charset") == -1) {
response.setCharacterEncoding(getEncoding());
}

scocai

2019-05-31 10:54

感谢波总,我试一下!