英文:
how to receive an entity with image from requestParam
问题
I'm trying to save an entity (Product) with many attributes, one of them, the picture. And I don't know how to get both (entity and image) in the controller.
@PostMapping
public ResponseEntity<?> create(@Valid @RequestBody Product product,
BindingResult result, @RequestParam("imageData") MultipartFile imageData);
If I put it this way I get an "Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'multipart/form-data;boundary=--------------------------889210147211052471233495;charset=UTF-8'" error.
If I only get the @RequestParam, because I suppose, I cannot use two both Request at the same time, I don't know how to send both, product and image.
And much less, I don't know yet how to send this information from the front-end in react.
export const ProductForm = ({ productSelected }) => {
const initialProductForm = {
id: 0,
productName: '',
description: '',
image: " ",
price: 0,
}
const { initialProductForm, handlerAddProduct, errors } = useProducts();
const [productForm, setProductForm] = useState(initialProductForm);
let { id, productName, description, image, price } = productForm;
const onInputChange = ({ target }) => {
const { name, value } = target;
setProductForm({
...productForm,
[name]: value,
})
}
const handleSubmit = (event) => {
event.preventDefault();
imageData.append('product', productForm);
imageData.append('imageName', imageName);
imageData.append('imageData', imageData);
handlerAddProduct(productForm);
}
const handleChange = event => {
setImageName(event.target.value)
};
const [imageData, setImageData] = useState(null);
const [imageName, setImageName] = useState("");
return (
<>
<form onSubmit={handleSubmit} method="POST" encType="application/json">
<input
className="form-control my-3 w-75"
placeholder="ProductName"
name="productName"
value={productName}
onChange={onInputChange}
/>
<p className="text-danger">{errors?.productName}</p>
<input type="number"
className="form-control my-3 w-75"
placeholder="Price"
name="price"
value={price}
onChange={onInputChange}
/>
<p className="text-danger">{errors?.price}</p>
<input
className="form-control my-3 w-75"
placeholder="Description"
name="description"
value={description}
onChange={onInputChange}
/>
<p className="text-danger">{errors?.description}</p>
<input
accept="image/*"
id="upload-profile-image"
name="image"
type="file"
onChange={handleUploadClick}
/>
<label htmlFor="upload-profile-image">
<Button
variant="contained"
color="primary"
component="span"
>
Change Image
</Button>
</label>
<TextField
fullWidth
label="Image Name"
margin="dense"
name="name"
onChange={handleChange}
required
value={imageName}
variant="outlined"
/>
<input
type="hidden"
name="id"
value={id}
/>
<button
className="btn btn-primary"
type="submit">
{id > 0 ? 'Update' : 'Create'}
</button>
</form>
</>
)
}
ProductService:
export const save = async (product) => {
try {
return await usersApi.post(`${BASE_URL}/products/addProduct`, product, imageData);
} catch (error) {
console.log("error " + error);
throw error;
}
}
I can't make the controller work even from Postman. Postman
And of course I'm completely lost on the React Front-end.
Please. Help
Thanks a lot.
To get the product and the image to do this: product.setImage() = image.getBytes();
英文:
I'm trying to save an entity (Product) with many attributes, one of them , the picture. And I don't know how to get both (entity and image) in the controller.
@PostMapping
public ResponseEntity<?> create(@Valid @RequestBody Product product,
BindingResult result, @RequestParam("imageData") MultipartFile imageData);
If i put it this way I get an "Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'multipart/form-data;boundary=--------------------------889210147211052471233495;charset=UTF-8' is not supported]" error.
If I only get the @RequestParam, because I suppose, I cannot use two both Request at the same time, I don't know how to send both, product and image.
And much less, I don't know yet how to send this information from the front-end in react.
export const ProductForm = ({ productSelected }) => {
const initialProductForm = {
id: 0,
productName: '',
description: '',
image: " ",
price: 0,
}
const { initialProductForm, handlerAddProduct, errors } = useProducts();
const [productForm, setProductForm] = useState(initialProductForm);
let { id, productName, description, image, price } = productForm;
const onInputChange = ({ target }) => {
const { name, value } = target;
setProductForm({
...productForm,
[name]: value,
})
}
const handleSubmit = (event) => {
event.preventDefault();
imageData.append('product',productForm);
imageData.append('imageName', imageName);
imageData.append('imageData', imageData);
handlerAddProduct(productForm);
}
const handleChange = event => {
setImageName(event.target.value)
};
const [imageData, setImageData] = useState(null);
const [imageName, setImageName] = useState("");
return (
<>
<form onSubmit={handleSubmit} method="POST" encType="application/json">
<input
className="form-control my-3 w-75"
placeholder="ProductName"
name="productName"
value={productName}
onChange={onInputChange}
/>
<p className="text-danger">{errors?.productName}</p>
<input type="number"
className="form-control my-3 w-75"
placeholder="Price"
name="price"
value={price}
onChange={onInputChange}
/>
<p className="text-danger">{errors?.price}</p>
<input
className="form-control my-3 w-75"
placeholder="Description"
name="description"
value={description}
onChange={onInputChange}
/>
<p className="text-danger">{errors?.description}</p>
<input
accept="image/*"
id="upload-profile-image"
name="image"
type="file"
onChange={handleUploadClick}
/>
<label htmlFor="upload-profile-image">
<Button
variant="contained"
color="primary"
component="span"
>
Change Image
</Button>
</label>
<TextField
fullWidth
label="Image Name"
margin="dense"
name="name"
onChange={handleChange}
required
value={imageName}
variant="outlined"
/>
<input
type="hidden"
name="id"
value={id}
/>
<button
className="btn btn-primary"
type="submit">
{id > 0 ? 'Update' : 'Create'}
</button>
</form>
</>
)
}
ProductService:
export const save = async (product) => {
try {
return await usersApi.post(`${BASE_URL}/products/addProduct`, product, imageData);
} catch (error) {
console.log("errrooorrr " + error);
throw error;
}
}
I can't make the controller work even from Postman. Postman
And of course I'm complete lost from React Front-end.
Please. Help
Thanks a lot.
To get the product and the image to do this: product.setImage()= image.getBytes();
答案1
得分: 1
这是您要翻译的内容:
-
尝试接收 JSON RequestBody 和图像/文件的同一请求是否可行还不确定。但您可以尝试以下方法:
- 将图像转换为 base64 字符串并将其添加到 JSON 请求中。这样,您可以将请求作为 RequestBody 接收,然后从中读取 base64 图像数据并将其转换为图像。
示例:
请求
{ "productName" : "Xbox", "description" : "Xbox", "price" : "500", "imageData" : "图像的 base64 字符串数据在这里" }
接收请求
@PostMapping("/json") public void readJsonRequest(@RequestBody(required = true) String jsonRequest) { JSONObject object = new JSONObject(jsonRequest); String productName = object.getString("productName"); String imageData = object.getString("imageData"); // 将 imageData 从 base64 转换为图像 }
-
以 ContentType: multipart/form-data 的形式发送请求。这样,您可以添加键,并使用 RequestParams 和 MultipartFile 接收它们。
示例
请求
Key Value productName Xbox description Xbox price 500 imageFile 选择的文件(.png、.jpg 等)
接收请求
@PostMapping("/request") public void readRequest( @RequestParam(value = "productName", required = true) String productName, @RequestParam(value = "description", required = true) String description, @RequestParam(value = "price", required = true) String price, @RequestParam(value = "imageFile", required = true) MultipartFile imageFile) { }
要将 JSON 对象作为实体发送,请确保 JSON 请求中的键/属性与实体类中的字段名称匹配。例如,JSON 请求中的 "productName" 键应与 Product 实体类中的 "private String productName" 匹配。
要接收它:
public ResponseEntity<?> create(@Valid @RequestBody Product product, BindingResult result) {
}
英文:
No sure if it's possible to receive JSON RequestBody and image/file in same request. But you can try approaches below
- Convert image to base64 string and add it to json request. This way you will be able to receive request as RequestBody from which you can read base64 image data and convert it to image.
Eg.
Request
{
"productName" : "Xbox",
"description" : "Xbox",
"price" : "500",
"imageData" : "image base64 string data here"
}
Receive request
@PostMapping("/json")
public void readJsonRequest(@RequestBody(required = true) String jsonRequest) {
JSONObject object = new JSONObject(jsonRequest);
String productName = object.getString("productName");
String imageData = object.getString("imageData");
//convert imageData from base64 to image
}
- Send request as ContentType: multipart/form-data. This way you can add keys and receive them using RequestParams & MultipartFile
E.g
Request
Key value
productName Xbox
description Xbox
price 500
imageFile selected file (.png, .jpg etc)
Receive request
@PostMapping("/request")
public void readRequest(@RequestParam(value = "productName", required = true) String productName,
@RequestParam(value = "description", required = true) String description,
@RequestParam(value = "price", required = true) String price,
@RequestParam(value = "imageFile", required = true) MultipartFile imageFile) {
}
To send Json object as entity, ensure keys/properties in json request matches fields names in your entity class. Eg productName
key in json request should match private String productName
in Product entity class.
To receive it
public ResponseEntity<?> create(@Valid @RequestBody Product product,
BindingResult result) {
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论