Я пытаюсь получить файл с RESTful API, основанный на JAX-RS на Grails. Файл отправляется из обычной многостраничной формы POST с тегом ввода файла. (Для отправки файла я использую postman google extention)
Но после отправки запроса я получаю ответ "HTTP Status 400 - Bad Request". Я проверил множество учебников и следил за их шагами, но он не работает.
Вот код в службе REST для обработки запроса:
import com.sun.jersey.multipart.FormDataParam
import com.sun.jersey.core.header.FormDataContentDisposition;
import org.json.simple.JSONObject
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.ws.rs.Consumes
import javax.ws.rs.FormParam
import javax.ws.rs.GET
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.Context
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.MultivaluedMap
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@Path('/api/upload/')
class UploadResource {
@POST
@Path("/tst")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces('application/json')
public String uploadFile(@FormDataParam("file") InputStream is, @FormDataParam("file") FormDataContentDisposition fileDetail){
String uploadedFileLocation = "Some Location";
// save it
saveToFile(is, uploadedFileLocation);
JSONObject JObject = new JSONObject();
JObject.put("Message", "Aha")
JObject.put("Response", "200")
JObject.put("Status", "OK")
return JObject.toJSONString()
}
}
И вот как я могу отправить файл:
Проблема возникает из-за того, что контроллер, инициированный плагином jaxrs, анализирует предварительный запрос, и это приводит к ошибке.
Эта проблема известна и есть обходной путь для этого: https://code.google.com/p/grails-jaxrs/issues/detail?id=52#c11 Но это все еще известная ошибка в плагине jaxrs.
Вместо того, чтобы полностью отключить многопользовательский резольвер Grails для всего приложения (см. Https://code.google.com/p/grails-jaxrs/issues/detail?id=52#c11), вы можете получить файл, обратившись к multipart файл от владельца Grails WebUtils.
@POST
@Path("/tst")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces('application/json')
public String uploadFile() {
String uploadedFileLocation = "Some Location";
// here is the workaround for issue: https://code.google.com/p/grails-jaxrs/issues/detail?id=52
GrailsWebRequest request = WebUtils.retrieveGrailsWebRequest()
MultipartFile multipartFile = request.getRequest().getFile('file')
def is = multipartFile.inputStream
// save it
saveToFile(is, uploadedFileLocation);
JSONObject JObject = new JSONObject();
JObject.put("Message", "Aha")
JObject.put("Response", "200")
JObject.put("Status", "OK")
return JObject.toJSONString()
}
По умолчанию Grails определяет bean с именем multipartResolver, определенный для CommonsMultipartResolver, но это не работает с jax-rs в соответствии с причинами, описанными Denny.
Единственная проблема, которую я вижу с его предложением использовать GrailsWebRequest, заключается в том, что если вы перейдете на YOUR_APP_URL/application.wadl, вы не увидите там параметр файла, и поэтому автоматически созданный клиентский код не будет работать.
То, что я сделал, переопределяет это в resources.groovy:
multipartResolver(org.springframework.web.multipart.support.StandardServletMultipartResolver) { bean ->
bean.autowire = 'byName'
}