Spring框架 @ResponseBody注解 编码问题: 论设置 Accept 的重要性

我写了这么个代码, 用来测试使用 spring 提供 Json 数据

Controller

package controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import service.json.FileService;

@Controller
public class IndexController {
	
	@ResponseBody
	@RequestMapping(value = "index", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
	public String index(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("请求内容: " + request.getHeader("Accept"));
		response.setContentType("text/html); charset=utf-8");
		return FileService.INSTANCE.getResList();
	}

}

Kotlin 处理逻辑

package service.json

import java.io.File
import my.kotlin.getFileSize

object FileService {
	fun getResList() : String {
		val dir = File("C:\\")
		var list = ""
		for (f in (dir.listFiles() ?: return "{}")) {
			list +=  """
					|	{"$f", "${ if (f.isFile()) "文件" else "目录" }", ${ f.getFileSize() }}
					|
					""".trimMargin()
		}
		return """
				|{
				|$list
				|}
				""".trimMargin()
	}
}

fun main() = Unit

请求结果

$ curl http://abc.com:8080/Json/index.html
{
        {"C:\$Recycle.Bin", "??", 0 Byte}
        {"C:\AppData", "??", 0 Byte}
        {"C:\Boot", "??", 4 KB}
        {"C:\bootmgr", "??", 374.79 KB}
        {"C:\CYGWIN_SYSLOG.TXT", "??", 876 Byte}
        {"C:\Documents and Settings", "??", 0 Byte}
        {"C:\dosh", "??", 0 Byte}
        {"C:\DownLoadRecord.ini", "??", 19 Byte}
        {"C:\GHLDR", "??", 265.78 KB}
        {"C:\hsrv.txt", "??", 0 Byte}
        {"C:\mypath_config.txt", "??", 2.7 KB}
        {"C:\my_path_eve_var.txt", "??", 2.8 KB}
        {"C:\OEMSF", "??", 317.54 KB}
        {"C:\pagefile.sys", "??", 7.93 GB}
        {"C:\perflogs", "??", 0 Byte}
        {"C:\ping.jpg", "??", 1.51 MB}
        {"C:\Program Files", "??", 8 KB}
        {"C:\Program Files (x86)", "??", 12 KB}
        {"C:\ProgramData", "??", 8 KB}
        {"C:\Sandbox", "??", 0 Byte}
        {"C:\System Volume Information", "??", 0 Byte}
        {"C:\Users", "??", 4 KB}
        {"C:\windmdll", "??", 0 Byte}
        {"C:\Windows", "??", 48 KB}

}  [15:30:56] Administrator@ ~

很明显, response.setContentType("text/html; charset=utf-8");这句代码是没有起到作用的, 在 Github 上我终于找到了问题的原因:

我想知道为什么这会有用?我认为客户有责任发送他们可以接受的contentType。然后消息转换器可以响应它。

设置 Accept 为 utf-8 编码

$ telnet abc.com 8080
GET /Json/index.html HTTP/1.1
Host: abc.com
Accept: text/json;charset=utf-8

HTTP/1.1 200
Content-Type: text/json;charset=utf-8
Content-Length: 924
Date: Thu, 05 Sep 2019 07:47:22 GMT

{
        {"C:\$Recycle.Bin", "目录", 0 Byte}
        {"C:\AppData", "目录", 0 Byte}
        {"C:\Boot", "目录", 4 KB}
        {"C:\bootmgr", "文件", 374.79 KB}
        {"C:\CYGWIN_SYSLOG.TXT", "文件", 876 Byte}
        {"C:\Documents and Settings", "目录", 0 Byte}
        {"C:\dosh", "目录", 0 Byte}
        {"C:\DownLoadRecord.ini", "文件", 19 Byte}
        {"C:\GHLDR", "文件", 265.78 KB}
        {"C:\hsrv.txt", "文件", 0 Byte}
        {"C:\mypath_config.txt", "文件", 2.7 KB}
        {"C:\my_path_eve_var.txt", "文件", 2.8 KB}
        {"C:\OEMSF", "文件", 317.54 KB}
        {"C:\pagefile.sys", "文件", 7.93 GB}
        {"C:\perflogs", "目录", 0 Byte}
        {"C:\ping.jpg", "文件", 1.51 MB}
        {"C:\Program Files", "目录", 8 KB}
        {"C:\Program Files (x86)", "目录", 12 KB}
        {"C:\ProgramData", "目录", 8 KB}
        {"C:\Sandbox", "目录", 0 Byte}
        {"C:\System Volume Information", "目录", 0 Byte}
        {"C:\Users", "目录", 4 KB}
        {"C:\windmdll", "目录", 0 Byte}
        {"C:\Windows", "目录", 48 KB}

}Connection closed by foreign host

设置 Accept 为 bgk 编码

posted @ 2019-09-05 15:51  develon  阅读(1055)  评论(0编辑  收藏  举报