I want to upload the file with spring boot and vue.
But, I have an error '415 : Unsupported MediaType'.
This is my spring boot controller.
#PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
#ResponseBody
#ApiOperation(value = "회원 가입", notes = "<strong>아이디와 패스워드</strong>를 통해 회원가입 한다.")
#ApiResponses({
#ApiResponse(code = 200, message = "성공"),
#ApiResponse(code = 401, message = "인증 실패"),
#ApiResponse(code = 404, message = "사용자 없음"),
#ApiResponse(code = 500, message = "서버 오류")
})
public ResponseEntity<User> register(
#RequestParam("file") MultipartFile file,) throws IllegalStateException, IOException, URISyntaxException {
...
}
And, this is my vue code.
<el-form-item prop="profileImg" label="프로필 사진" :label-width="state.formLabelWidth" >
<input #change="fileSelect()" id="profileimg" type="file" accept="image/*">
</el-form-item>
const formData = new FormData()
formData.append('userId', state.form.userId)
formData.append('userName', state.form.userName)
formData.append('password', state.form.password)
formData.append('age', state.form.age)
formData.append('gender', state.form.gender)
formData.append('phoneNum', state.form.phoneNum)
formData.append('email', state.form.email)
formData.append('mbti', state.form.mbti)
formData.append('guide', state.form.guide)
formData.append('file', state.form.profileImg)
profileImg ({ commit }, payload) {
return axios
.post(`${BASE_URL}/api/v1/users`, payload,
{
headers: {
"Accept": "*/*",
"Content-Type": "multipart/form-data"
}
}
)
}
I tried #RequestPart MultipartFile file, but had the same error.
How can I fix it?
Sorry, I can't add comments, this answer is just my guess
what if you output
request.getHeader(HttpHeaders.CONTENT_TYPE);
Content-Type may have been changed if your request pass through Nginx or other agent
I found an answer here on GitHub
All you have to do is change
#RequestParam("file") MultipartFile file)
with :
#RequestParam("file") FilePart file)
Related
I built a dummy api and I want to test it on swagger. The swagger.json has been successfully generated and executed to show the swagger UI.
But there is the 404 error that cannot find the response part.
How can I solve this?
This is the built swagger UI.
And this is the code.
#Service
#Api
public class className () {
#GET
#Path("/oauth2/authorize")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#ApiOperation(value = "Authorization Grant", notes = "Authorization Grant")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Successfully Granted the Authorization"),
#ApiResponse(code = 400, message = "Missing or invalid request body"),
#ApiResponse(code = 403, message = "Forbidden"),
#ApiResponse(code = 404, message = "Schema not found"),
#ApiResponse(code = 500, message = "Internal error")})
public Response authorizationGrant(
#HeaderParam("X-AUTH-TOKEN") final String token,
#HeaderParam("X-CSRF-TOKEN") final String csrftoken,
#ApiParam(value = "Client ID", required = true) #QueryParam("Client ID") final String clientId,
#ApiParam(value = "Scope", required = true) #QueryParam("Scope") final String scope,
#ApiParam(value = "Redirect Uri", required = true) #QueryParam("Redirect Uri") final String redirectUri,
#ApiParam(value = "Response Type", required = true) #QueryParam("Response Type") final String responseType ) throws AccessDeniedException {
return Response
.status(Response.Status.OK)
.entity("{\"hello\": \"This is a JSON response\"}")
.type(MediaType.APPLICATION_JSON)
.build();
}
}
Please tell me what you need more to be clear with this error.
The problem solved!!!
I hope this answer could help for others who are suffered from this trouble. :)
The error was from the #Api Definition part. I should have define the path in that part.
This is the corrected code.
#Path("/oauth2")
#Service
#Api
public class className () {
.....
#GET
#Path("/authorize")
.....
}
As you can see the #Api definition part requires the #Path annotation.
:)
#PostMapping
public UserResponse createUser(#RequestBody UserRequest userDetail) {
UserResponse returnValue = new UserResponse();
UserDto userDto = new UserDto();
BeanUtils.copyProperties(userDetail, userDto);
UserDto storedData = userService.createUser(userDto);
BeanUtils.copyProperties(storedData, returnValue);
return returnValue;
}
this is the code I am getting this error
{
"timestamp": "2020-05-13T12:24:04.866+0000",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported",
"path": "/users"
}
I have tried a lot of different ways still not getting the solution
This is the image from the postman
image from postman
Are you using Postman to fire the request? you might want to check these settings
Edit. Add another image for troubleshooting
That because your service is only accepting application/json content type. If you want to accepting application/x-www-form-urlencoded you can add consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE inside #PostMapping annotation
bellow is sample of service that accept application/json and give application/json response.
#PostMapping(path = "/v1/agent/create", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ApiResponseWrapperDto createAgent(#RequestBody ApiRequestWrapperDto request) throws Exception {
return this.agentManagementApiHandler.createAgent(request);
}
Hope this solve your problem.
Thanks
I use Jhipster and this is a controller method:
Controller:
#RequestMapping(value = UPLOAD_URL, method = {RequestMethod.POST},
headers = {"content-type=multipart/mixed", "content-type=multipart/form-data"},
consumes = {"multipart/form-data"})
public ResponseEntity<?> uploadWithMetaData(#RequestPart(value = "file") MultipartFile file,
#RequestPart(value = "documentDTO") DocumentDTO documentDTO,
Locale locale) throws IOException, URISyntaxException, JSONException {
// business logic
}
Essentially I want to post a file and also a json object.
I my integration test, I can verify that it works as expected:
Integration test:
DocumentDTO documentDTO = getDocumentDTOMockFile();
Long originId = originRepository.findAll().stream().findFirst().get().getId();
documentDTO.setOriginId(originId);
MockMultipartFile jsonFile = new MockMultipartFile("documentDTO", "", "application/json",
jsonUtils.toJson(documentDTO, null).getBytes());
restClientMockMvc
.perform(MockMvcRequestBuilders.fileUpload("/api/v1/documents/upload")
.file(fstmp)
.file(jsonFile))
.andDo(MockMvcResultHandlers.log())
.andExpect(status().isOk());
}
Angular frontend:
let fd: FormData = new FormData();
let file = fileForm.files[0];
fd.append("file", file);
let documentDTO = JSON.stringify(document);
fd.append("documentDTO",new Blob([JSON.stringify({
"documentDTO": documentDTO})], {
type: "application/json"
})
);
his.httpClient.post("/api/v1/documents/upload", fd ).subscribe(request => {
console.log("request", request);
});
I got an interceptor that sets the content-type in the request headers to:
Content-Type:multipart/form-data; boundary=----WebKitFormBoundary4PnIOSOLe5Djj95R
This is how the Request payload looks like:
This is the spring boot log message:
Resolved exception caused by Handler execution: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
This is the response I see in the browser:
{
"type" : "http://www.jhipster.tech/problem/problem-with-message",
"title" : "Bad Request",
"status" : 400,
"detail" : "Required request part 'file' is not present",
"path" : "///api/v1/documents/upload",
"message" : "error.http.400"
}
What I've tried:
setting content-type to 'Content-Type' : 'multipart/mixed' => result same
Creating a pojo with the dto and the file, using #ModelAttribute => same error
Then I checked if I got a Multipart Resolver, got it
I'm out of ideas, someone any suggestions?
Post as a multipart-form from the JavaScript and use something like this:
final WebRequest webRequest,
#RequestParam("fileContent") final MultipartFile fileContent,
#RequestParam("inputJson") String inputJsonString
as the parameters.
The WebRequest is useful if you need to access the session.
I have back-end API to allow user POST a json_body and with a file:
#RequestMapping(value = "/sendemail",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}
)
public #ResponseBody ResponseEntity<String> sendEmailToClients(
#RequestBody String jsonData,
#RequestParam(value = "file", required = false) final MultipartFile file) {
...
}
Question: On Postman Tool, Is there any way to make a POST for sending out json_body and file upload?
I have a REST endpoint that is used to POST data. So far, I've documented in using swagger as below.
#POST
#OPTIONS
#Path("{serviceVersion}/{dataType}")
#Produces({MediaType.TEXT_PLAIN})
#Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
#ApiOperation(value = "Post to Application",
notes = "End Point to post Data")
#ApiResponses(value = { #ApiResponse(code = 200, message = "Success"),
#ApiResponse(code = 400, message = "Bad Request"),
#ApiResponse(code = 500, message = "Internal server error (NON-retryable)") })
public String postData(#Context HttpServletRequest req,
#Context HttpServletResponse resp,
#ApiParam(value = "Service Version. Ex: v1", required = true, defaultValue="v1") #PathParam("serviceVersion")String serviceVersion,
#ApiParam(value = "Topic Name", required = true, defaultValue="topic") #PathParam("dataType")String dataType,
#ApiParam(value = "Delivery Mode", required = false) #QueryParam("deliveryMode")#DefaultValue("persistent") String deliveryMode,
#Context UriInfo uriInfo);
How can I document #Context HttpServletRequest req? I need this because I want to let user's submit data from swagger-UI.
PS: The way data is actually read from the request is request.getReader(); or request.getInputStream();