Я создал службу загрузки файлов с помощью Spring MVC с поддержкой многочастного распознавателя apache commons, которая указывает, что файл должен быть присоединен как часть многочастного запроса HTTP Post.Запрос также содержит параметр, содержащий строку XML с метаданными об объекте.XML можно маршалировать с помощью JAXB.
Другие сервисы, которые не являются многочастными, прозрачно обрабатывают маршаллинг, например:
@RequestMapping(value = "/register", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public ModelAndView createUser(@RequestBody CreateUserDTO createUserDTO) throws Exception {
UserDTO user = userService.createUser(createUserDTO);
return createModelAndView(user);
}
Здесь CreateUserDTO - аннотированный объект JAXB, который автоматически маршалируется.В многочастном случае я хотел бы иметь такую же прозрачность.В идеале я хотел бы сделать следующее:
RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public ModelAndView createAttachment(@RequestParam AttachmentDTO attachment,
HttpServletRequest request) throws Exception {
final MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
AttachmentDTO attachment = null;
final MultipartFile dataFile = multipartRequest.getFile("data");
AttachmentDTO createdAttachment = attachmentService.createAttachment(attachment,
dataFile);
return createModelAndView(createdAttachment);
}
К сожалению, это не работает.Я могу связать параметр вложения как String, но автоматическая сортировка не работает.Моя работа заключается в том, чтобы вручную выполнить маршалинг, как показано ниже, но мне не нравится этот подход (тем более что параметр может быть указан как в форме JSON, так и в формате XML):
@Autowired
private Jaxb2Marshaller jaxb2Marshaller;
@Autowired
private ObjectMapper jacksonMapper;
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public ModelAndView createAttachment(@RequestParam(ATTACHMENT_PARAMETER) String attachmentString,
final HttpServletRequest request) throws Exception {
final MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
AttachmentDTO attachment = null;
try {
attachment = (AttachmentDTO)jaxb2Marshaller.unmarshal(new StreamSource(new StringReader(attachmentString)));
} catch (XmlMappingException e) {
//Try JSON
try {
attachment = jacksonMapper.readValue(attachmentString, AttachmentDTO.class);
} catch (IOException e1) {
throw new BadRequestException("Could not interpret attachment parameter, both JSON and XML parsing failed");
}
}
У кого-нибудь естьлучшее предложение для решения этой проблемы?
Для полноты я также указываю соответствующую конфигурацию Spring здесь:
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1"/>
<property name="favorPathExtension" value="true"/>
<property name="ignoreAcceptHeader" value="false"/>
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="modelKey" value="object"/>
<property name="marshaller" ref="jaxbMarshaller"/>
</bean>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="objectMapper" ref="jaxbJacksonObjectMapper"/>
</bean>
</list>
</property>
</bean>
<!--Use JAXB OXM marshaller to marshall/unmarshall following class-->
<bean id="jaxbMarshaller"
class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.behindmedia.btfd.model.dto"/>
</bean>
<bean id="jaxbJacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>
<!-- allows for integration of file upload functionality -->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="maxUploadSize" value="100000000"/>
</bean>