使用Spring rest控制器上传文件不起作用

时间:2017-12-13 15:02:18

标签: spring resttemplate spring-restcontroller

我正在编写两个应该通过REST进行通信的应用程序。两个应用程序都是SpringBoot应用程序。大多数Web服务都运行正常但我在上传文件时遇到了一些问题。这是我的休息控制器:

@RestController
@RequestMapping(PathConstants.SERVER_PACKAGING_INTERFACE + "/**")
public class PackagingCommunication {
    //@PostMapping(PathConstants.SERVER_UPLOAD_FILE)
    @RequestMapping(name = PathConstants.SERVER_UPLOAD_FILE, method = RequestMethod.POST, headers=("content-type=multipart/*"))
    public ResponseEntity<String>  uploadFileInStorage(@RequestParam("file") MultipartFile file,
            RedirectAttributes redirectAttributes) {
        try {
            InputStream inputStream = file.getInputStream();
            String fileName = file.getOriginalFilename();
            //storageService.saveInputStreamInStorage(inputStream, fileName);
            return ResponseEntity.status(HttpStatus.OK).build(); 
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}

我的客户端有休息模板:

public void uploadeFileToStorage(File file, String serverUrl) {
    try{
        final MultiValueMap<String, Object> parameterMap = createMultipartFileParam(file.getAbsolutePath());
        parameterMap.add("file", file);
        HttpHeaders headers = new HttpHeaders();
        //headers.set("Content-Type", "multipart/form-data");
        //headers.set("Accept", "text/plain");
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        String url = serverUrl + PathConstants.SERVER_PACKAGING_INTERFACE + PathConstants.SERVER_UPLOAD_FILE;
        restTemplate = getRestTemplate();
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<MultiValueMap<String, Object>>(parameterMap, headers), 
                String.class);
        System.out.println(response.getHeaders().getAccept());
    } catch(Exception ex) {
        System.out.println(ex.getMessage());
    } finally {
        // Delete the file from the temporary directory of the client.
        file.delete();
    }
}

我收到了http错误代码400。注释行显示我试图解决问题的陈述。然后我编写了一个html formular,试图在没有我的Java程序的情况下与Web服务进行通信。

<html>
<body>
    <div>
        <form method="POST" enctype="multipart/form-data" action="http://localhost:9292/serverPackaging/uploadFile">
            <table>
                <tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
                <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
            </table>
        </form>
    </div>

</body>
</html>

它也不起作用。我收到错误“必需的请求部分'文件'不存在”。我不知道该怎么办。 html公式并不重要。非常重要的是在休息模板的帮助下两个应用程序之间的通信。

这是stacktrace:

org.springframework.web.client.HttpClientErrorException: 400 null
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
    at de.feu.kdmp4.packagingtoolkit.client.operations.classes.ServerCommunicationOperationsImpl.uploadeFileToStorage(ServerCommunicationOperationsImpl.java:314)
    at de.feu.kdmp4.packagingtoolkit.client.operations.facade.OperationsFacade.uploadeFileToStorage(OperationsFacade.java:49)
    at de.feu.kdmp4.packagingtoolkit.client.service.classes.ArchiveServiceImpl.addFileReference(ArchiveServiceImpl.java:69)
    at de.feu.kdmp4.packagingtoolkit.client.service.facades.ServiceFacade.addFileReference(ServiceFacade.java:48)
    at de.feu.kdmp4.packagingtoolkit.client.view.prime.managedBeans.InformationPackageCreationBean.createInformationPackage(InformationPackageCreationBean.java:192)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:247)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:814)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:108)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
    at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
    at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

有没有人知道我做错了什么?

谢谢, 克里斯托弗

1 个答案:

答案 0 :(得分:0)

调整@RequestMapping注释。将name字段替换为value

下面是一个对我很有用的例子,也许它可以帮到你。只需忽略代码示例的上下文:

@PostMapping("/recipe/{id}/image")
public String handleImagePost(@PathVariable String id, 
@RequestParam("file") MultipartFile file) {

    log.debug("received a file for recipe with id: " + recipeId);

    try{
        Recipe recipe = recipeRepository.findById(recipeId).get();
        Byte[] byteObjects = new Byte[file.getBytes().length];

        int i = 0;

        for(byte b: file.getBytes()){
            byteObjects[i++] = b;
        }

        recipe.setImage(byteObjects);
        recipeRepository.save(recipe);

    }catch(IOException e){
        log.error("Error occured while persisting the file. " + e);
        e.printStackTrace();
    }

    return "redirect:/recipe/" + id + "/show";
}

和相应的HTML:

<form  action="http://localhost/recipe/1/image" method="post" enctype="multipart/form-data">
            <label class="control-label">Select File</label>
            <input id="file" name="file" type="file" class="file">
            <button type="submit" class="btn btn-primary">Submit</button>
 </form>