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

如何通过jQuery.ajax发送含String与Blob的对象至Spring REST并接收?

Got it, let's walk through this end-to-end—from sending the data with jQuery.ajax to receiving it in Spring, mapping to a custom model, and saving everything to the database. Here's how to make it work:

1. Frontend: jQuery.ajax Request with String + Blob

Since JSON doesn't natively support Blob types, we'll use FormData to package both the string and blob data. This is the most reliable way to send mixed data types via AJAX.

// Assume you have a string value and a Blob (e.g., from a file input)
const textValue = "Hello from frontend!";
const fileBlob = document.getElementById("fileInput").files[0]; // This is a Blob

// Create FormData and append your data
const formData = new FormData();
formData.append("textContent", textValue);
formData.append("fileBlob", fileBlob);

// Send via jQuery.ajax
$.ajax({
    url: "/api/upload",
    type: "POST",
    data: formData,
    contentType: false, // Critical: Let browser set correct multipart boundary
    processData: false, // Critical: Prevent jQuery from converting FormData to string
    success: function(response) {
        console.log("Upload successful:", response);
    },
    error: function(xhr) {
        console.error("Upload failed:", xhr.responseText);
    }
});

Why contentType: false and processData: false? The browser automatically sets the correct multipart/form-data header with a boundary when using FormData, so we don't want jQuery overriding that. Disabling processData stops jQuery from trying to serialize the FormData object into a query string.

2. Backend: Custom Model Class

We'll create a model class to map the incoming FormData fields. Since Spring handles Blobs from multipart requests as MultipartFile, our model will include that type along with the string field.

import org.springframework.web.multipart.MultipartFile;
import lombok.Data;

// Use @Data from Lombok to auto-generate getters/setters (optional but convenient)
@Data
public class MyModel {
    private String textContent; // Matches the "textContent" key in FormData
    private MultipartFile fileBlob; // Matches the "fileBlob" key in FormData
}

If you don't use Lombok, just add manual getter and setter methods for both fields—Spring needs these to bind the request data to the model.

3. Spring REST Controller with @RequestBody

By default, Spring uses @ModelAttribute to bind multipart/form-data requests to model objects, but if you specifically need to use @RequestBody, we need to add a custom message converter to handle multipart data with Jackson.

First, the controller:

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/upload")
public class UploadController {

    private final MyDataService dataService;

    // Constructor injection (preferred over @Autowired)
    public UploadController(MyDataService dataService) {
        this.dataService = dataService;
    }

    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<String> uploadData(@RequestBody MyModel myModel) {
        try {
            dataService.saveToDatabase(myModel);
            return ResponseEntity.ok("Data saved successfully");
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("Save failed: " + e.getMessage());
        }
    }
}

Next, configure the message converter to let Jackson parse multipart requests into your model:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.MultipartJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(java.util.List<org.springframework.http.converter.HttpMessageConverter<?>> converters) {
        converters.add(multipartJackson2HttpMessageConverter());
    }

    @Bean
    public MultipartJackson2HttpMessageConverter multipartJackson2HttpMessageConverter() {
        MultipartJackson2HttpMessageConverter converter = new MultipartJackson2HttpMessageConverter();
        converter.setObjectMapper(new ObjectMapper());
        return converter;
    }
}

Note: If you don't strictly need @RequestBody, using @ModelAttribute is simpler—just replace @RequestBody with @ModelAttribute in the controller method, and you can skip the message converter configuration.

4. Saving to the Database

First, define your JPA entity to map to the database table. We'll store the Blob as a byte[] (annotated with @Lob to mark it as a large object):

import jakarta.persistence.*;
import lombok.Data;

@Entity
@Table(name = "uploaded_data")
@Data
public class MyDataEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String textContent;

    @Lob // Marks this as a BLOB type in the database
    private byte[] fileData;
}

Then create a repository interface:

import org.springframework.data.jpa.repository.JpaRepository;

public interface MyDataRepository extends JpaRepository<MyDataEntity, Long> {
}

Finally, the service layer to handle converting the model to the entity and saving:

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@Service
public class MyDataService {

    private final MyDataRepository repository;

    public MyDataService(MyDataRepository repository) {
        this.repository = repository;
    }

    public void saveToDatabase(MyModel myModel) throws IOException {
        MyDataEntity entity = new MyDataEntity();
        entity.setTextContent(myModel.getTextContent());
        // Convert MultipartFile to byte[] for database storage
        entity.setFileData(myModel.getFileBlob().getBytes());
        repository.save(entity);
    }
}

Key Notes

  • Make sure the field names in MyModel exactly match the keys you used in FormData.append()—Spring uses these names to bind the data.
  • If you're dealing with large Blobs, check your database's maximum BLOB size limit (e.g., MySQL's max_allowed_packet).
  • Handle exceptions properly (like IOException when reading the MultipartFile) to avoid unhandled errors in your controller.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:32:38