Spring Boot实现含图片的患者注册表单保存(需用@ModelAttribute)
问题修复方案
核心问题分析
- 实体类用
String存储图片二进制数据存在编码乱码、存储效率低的问题,应改用二进制数组存储 - 服务层方法未执行数据库持久化操作,也未处理图片数据转换
- 控制器拆分接收参数不符合
@ModelAttribute单参数绑定的需求
修正后的实体类
将图片字段改为二进制数组,并添加临时属性接收上传文件(不持久化到数据库):
@Entity @Getter @Setter @NoArgsConstructor // JPA要求必须有无参构造,替换原RequiredArgsConstructor @ToString @Table(name = "patient_registration") public class PatientRegistrationEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String patientName; private String salutation; private String age; private String patientPhone; private String patientAddress; private String gender; private String religion; private String dateOfBirth; private String marritalStatus; private String fatherName; private String motherName; @Lob @Column(columnDefinition = "LONGBLOB") // 适配MySQL大图片存储 private byte[] patientImage; // 临时属性:接收前端上传的文件,不参与数据库持久化 @Transient private MultipartFile imageFile; }
修正后的服务类
完善业务逻辑,处理图片转换并执行数据库保存:
@Service public class PatientRegistrationService { private final PatientRegistrationRepository repository; // 构造注入替代@Autowired,符合Spring最佳实践 public PatientRegistrationService(PatientRegistrationRepository repository) { this.repository = repository; } public List<PatientRegistrationEntity> getPatientList(){ return repository.findAll(); } public PatientRegistrationEntity createPatient(PatientRegistrationEntity patient) throws IOException { // 处理上传图片:将MultipartFile转换为byte[]存入实体 if (patient.getImageFile() != null && !patient.getImageFile().isEmpty()) { patient.setPatientImage(patient.getImageFile().getBytes()); } // 保存到数据库 return repository.save(patient); } }
修正后的控制器类
使用单一@ModelAttribute接收完整表单数据(含图片):
@RestController @RequestMapping("/patient/") @CrossOrigin(origins = "http://localhost:4200", allowCredentials = "true") public class PatientRegistrationController { private final PatientRegistrationService registrationService; // 构造注入 public PatientRegistrationController(PatientRegistrationService registrationService) { this.registrationService = registrationService; } @PostMapping(value = "post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity<PatientRegistrationEntity> savePatient(@ModelAttribute PatientRegistrationEntity patient) throws IOException { PatientRegistrationEntity savedPatient = registrationService.createPatient(patient); return ResponseEntity.ok(savedPatient); } }
关键注意事项
- 前端提交表单时必须设置
Content-Type: multipart/form-data,表单字段名需与实体类属性名完全对应(如图片字段对应imageFile) - Postman测试时选择
form-data格式,图片字段的Key设为imageFile,类型选择File并上传图片文件 - 确保数据库支持
LONGBLOB类型(MySQL默认支持,其他数据库可调整对应大字段类型)
内容的提问来源于stack exchange,提问作者Mahadi Hasan
相关产品推荐
相关产品推荐

