问题提出
传的数据格式如下:
article = { title: '字符串', content: '字符串', sectionId: 1, file: (文件), tags: [{tagId: 1, tagName: "qwe"}, {tagId: 2, tagName: "asd"}...] }
最初, 后端准备直接用一个DTO来接收:
@RequestMapping(value = "/", method = RequestMethod.POST) public ResponseEntity<SingleKeyVO> createArticle(ArticleCreateDTO articleDTO)
ArticleCreateDTO:
@Data @NoArgsConstructor @AllArgsConstructor public class ArticleCreateDTO implements Serializable { /** * 作者的id */ @JsonProperty("authorId") private Integer authorId; /** * Article-文章Id */ @JsonProperty("articleId") private String articleId; /** * Article-文章标题 */ @JsonProperty("title") private String title; /** * Article-文章内容 */ @JsonProperty("content") private String content; /** * 文章封面图片 */ @JsonProperty("file") MultipartFile file; /** * 文章分区id */ @JsonProperty("sectionId") private Integer sectionId; /** * Tag-文章标签 */ @JsonProperty("tags") private List<TagIdAndNameVO> tags;
TagIdAndNameVO:
@Data @NoArgsConstructor @AllArgsConstructor public class TagIdAndNameVO implements TagVO, Serializable { @JsonProperty("tagId") private String tagId; @JsonProperty("tagName") private String tagName; }
然而SpringMVC并不能解析其中的对象数组(tags),将List<TagIdAndNameVO> 改为 TagIdAndNameVO[] 也无效,所以开始寻求解决方法...
第一个找到的方法时在控制器方法的DTO形参处加@RequestBody注解:
@RequestMapping(value = "/", method = RequestMethod.POST) public ResponseEntity<SingleKeyVO> createArticle(@RequestBody ArticleCreateDTO articleDTO)
此时会返回状态码415,原因是前端传来的数据中包含文件。所以将 content-type 改为了 multipart/form-data,但@RequestBody 注解不支持该类型,所以也行不通...
问题解决
后来又看到一位网友说可以先将对象数组转为字符串,后端再通过工具将字符串转为List, 操作如下:
1、前端先将数组转为字符串
let data = new FormData() data.append("title", topic.title) data.append("file", topic.file) data.append("content", topic.content) data.append("sectionId", topic.sectionId) // 使用JSON.stringify 方法 data.append("tags", JSON.stringify(topic.tags)) // 注:传给后端的数据包含文件时,需要使用FormData() 否则文件无法传递到后端(前端知识浅薄,不一定对)
2、再修改后端DTO(其他的不变,将tags 改为String 类型即可)
public class ArticleCreateDTO implements Serializable { /** * Tag-文章标签 */ @JsonProperty("tags") private String tags; }
3、使用fastjson 将 String 转为List
List<TagIdAndNameVO> tagList = JSON.parseArray(articleCreateDTO.getTags(), TagIdAndNameVO.class);
至此,问题解决,但解决方式仍不够“优雅”,还需要继续学习...