Загрузка изображений API работает от почтальона и чванства, но не от приложения реагирования.
Всегда отвергая с 415 -
ошибка: неподдерживаемый тип носителя и
исключение - org.springframework.web.HttpMediaTypeNotSupportedException
сообщение - "Тип содержимого" multipart / form-data; border = ---- WebKitFormBoundaryzA5My2dyhAyxoPIZ 'не поддерживается ",
Код API загрузки изображений выглядит следующим образом в Spring Boot -
@RequestMapping(value = {"/profilepic/{userId}", "/profilepic/{userId}/"}, method = RequestMethod.POST)
public DeferredResult<ResponseEntity<GenericResponseREST>> uploadEmployeePicture(
@Valid @NotNull @PathVariable(value = "userId") Integer employeeId,
@NotNull @RequestParam("file") MultipartFile file,
HttpServletRequest servletRequest) throws URISyntaxException {
DeferredResult<ResponseEntity<GenericResponseREST>> result = new DeferredResult<>();
userControllerAsync.uploadEmployeePicture(result, employeeId, file, clientInfoService.generateRequestorInfo(servletRequest));
return result;
}
Это работает. Мы проверили как от чванства, так и от почтальона. Хотя от почтальона, если мы предоставим какой-либо тип контента, он потерпит неудачу, только если мы оставим тип контента пустым, он будет работать.
Во всяком случае, в моем приложении Reaction-Redux я использовал загрузку antd для загрузки файла и загрузку файла с помощью fetch-whatwg. Вот код загрузки antd -
export default class extends Component {
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
notification('error', 'You can only upload JPG file!', '');
return false;
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
notification('error', 'Image must smaller than 2MB!', '');
return false;
}
return true;
}
render() {
const {user, uploadProfilePicture} = this.props;
const onImageUpload = function (info) {
const reader = new FileReader();
reader.onloadend = (obj) => {
const imageDataAsURL = obj.srcElement.result;
uploadProfilePicture(user.id, imageDataAsURL);
};
reader.readAsDataURL(info.file.originFileObj);
};
return (<Upload
className="avatar-uploader"
name="avatar"
showUploadList={false}
beforeUpload={this.beforeUpload}
//customRequest={this.upload}
onChange={onImageUpload}
>
{user.avatar ? (
<img src={user.avatar} alt="" className="avatar"/>
) : (
<img alt="#" src='https://i.stack.imgur.com/l60Hf.png'/>
)}
<Icon type="plus" className="avatar-uploader-trigger"/>
</Upload>
);
Код вызова API с fetch-whatwg подобен приведенному ниже -
function uploadProfilePicture(id, file) {
const updateUserURL = API_BASE_URL + USERS.UPDATE + id;
var formData = new FormData();
formData.append('file', file);
const options = {
method: 'POST',
headers: {
Accept: 'application/json',
// 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryzA5My2dyhAyxoPIZ',
'token': authService.getTokenFromLocalStorage()
},
body: formData
};
return fetch(updateUserURL, options)
.then((response) => {
if (response.status === 200) {
return response.json();
}
const error = new Error(response.statusText);
error.response = response;
throw error;
})
.then((response) => {
return response.user;
});