You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring ModelAttribute中将字节数组转换为字符串?

嗨,这个问题我之前做CKEditor集成的时候也遇到过,其实核心就是要在Spring数据绑定和数据库交互的环节,把字节数组和字符串做无缝转换,结合你的场景,有几个实用的解决办法:

方案一:给实体类加辅助属性(最省心的快速方案)

不用改动太多业务代码,只需要在Post类里新增一个字符串类型的辅助属性,通过它的getter/setter自动完成和原byte[]属性的转换,完美适配Spring表单的modelAttribute绑定:

import java.nio.charset.StandardCharsets;

public class Post{
    private byte[] postContent;
    
    // 新增辅助属性,专门给Spring表单绑定用
    private String postContentStr;

    // 原byte[]属性的getter/setter,保持给数据库操作使用
    public byte[] getPostContent() {
        return postContent;
    }

    public void setPostContent(byte[] postContent) {
        this.postContent = postContent;
        // 从数据库取出字节数组时,自动转成UTF-8字符串赋值给辅助属性
        if (postContent != null) {
            this.postContentStr = new String(postContent, StandardCharsets.UTF_8);
        }
    }

    // 辅助属性的getter/setter,给Spring表单绑定用
    public String getPostContentStr() {
        return postContentStr;
    }

    public void setPostContentStr(String postContentStr) {
        this.postContentStr = postContentStr;
        // 表单提交字符串时,自动转成UTF-8字节数组赋值给原属性
        if (postContentStr != null) {
            this.postContent = postContentStr.getBytes(StandardCharsets.UTF_8);
        }
    }
}

然后修改JSP里的表单标签,把path指向新增的辅助属性:

<form:form ...... modelAttribute="post">
 ...
 <form:textarea path="postContentStr" id="editor1">
 ....
 </form:form>

这样不管是从数据库取数据回显,还是表单提交保存,转换都会自动完成,控制器代码完全不用改。

方案二:在控制器层手动处理转换(适合不想改实体类的场景)

如果不想修改实体类结构,可以在从数据库取数据后,手动把字节数组转成字符串放到Model里,回显时用普通文本域而非Spring表单标签:

回显数据时的控制器代码:

import java.nio.charset.StandardCharsets;
// ...
Post post = postService.findByPostId(postId);
if (post != null) {
    mv.addObject("title", "Edit Post");
    // 把字节数组转成UTF-8字符串,单独放到Model中
    if (post.getPostContent() != null) {
        String contentStr = new String(post.getPostContent(), StandardCharsets.UTF_8);
        mv.addObject("postContentStr", contentStr);
    }
    mv.addObject("post", post);
    // ...
}

JSP里的回显代码:

<form:form ...... modelAttribute="post">
 ...
 <!-- 用普通textarea,直接通过EL表达式赋值回显内容 -->
 <textarea id="editor1" name="postContent">${postContentStr}</textarea>
 ....
 </form:form>

表单提交时的控制器处理:

提交时需要把接收的字符串转成字节数组再赋值给Post对象:

@RequestMapping(value = "/edit", method = RequestMethod.POST)
public String editPost(@ModelAttribute("post") Post post, @RequestParam("postContent") String content) {
    post.setPostContent(content.getBytes(StandardCharsets.UTF_8));
    postService.updatePost(post);
    return "redirect:/posts";
}

方案三:全局注册类型转换器(最优雅的Spring风格方案)

如果项目里有很多类似的byte[]和String互转场景,可以自定义Spring转换器,让框架自动处理类型转换,完全不用改动实体类和表单代码:

第一步:定义转换器类

import org.springframework.core.convert.converter.Converter;
import java.nio.charset.StandardCharsets;

// 字节数组转字符串
public class ByteArrayToStringConverter implements Converter<byte[], String> {
    @Override
    public String convert(byte[] source) {
        return source == null ? null : new String(source, StandardCharsets.UTF_8);
    }
}

// 字符串转字节数组
public class StringToByteArrayConverter implements Converter<String, byte[]> {
    @Override
    public byte[] convert(String source) {
        return source == null ? null : source.getBytes(StandardCharsets.UTF_8);
    }
}

第二步:注册转换器到Spring容器

创建一个Web配置类,把转换器注册进去:

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new ByteArrayToStringConverter());
        registry.addConverter(new StringToByteArrayConverter());
    }
}

做完这两步,你原来的实体类和表单代码完全不用改,Spring会自动在表单绑定和数据流转时完成byte[]和String的互转,非常优雅!

重要提醒

不管用哪种方案,一定要显式指定字符集(比如StandardCharsets.UTF_8),避免因为环境默认字符集不同导致的乱码问题。

内容的提问来源于stack exchange,提问作者DJSarma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:37:35