【发布时间】:2019-11-22 05:31:29
【问题描述】:
我正在处理 Angular 项目,同时我想将我的图像文件上传到 Web 服务器。我正在使用 Spring Web 服务来上传这些文件。 我从 Youtube 视频中观看了这段代码。 我使用的 HTML 是:
<div class="container-fluid">
<h2>Entering a product</h2>
<h4 *ngIf="submitted" class="text-success text">{{product_NAME.value}} has been submitted successfull.</h4>
<form [formGroup]="insertProduct" (ngSubmit)="onSubmit()">
{{insertProduct.value | json}}
<div class="form-group">
<label for="product_NAME">Product Name:</label>
<input required type="text" name="product_NAME" formControlName="product_NAME" class="form-control">
</div>
<div class="form-group">
<label for="product_PRICE">Sale Price:</label>
<input required type="number" name="product_PRICE" formControlName="product_PRICE" class="form-control">
</div>
<div class="form-group">
<label for="product_STOCK">Stock:</label>
<input required type="number" name="product_STOCK" formControlName="product_STOCK" class="form-control">
</div>
<div class="form-group">
<label for="product_DESCRIPTION">Description:</label>
<textarea required class="form-control" rows="5" formControlName="product_DESCRIPTION"></textarea>
</div>
<div class="form-group">
<select formControlName="productcategory_ID" class="custom-select" name="productcategory_ID" [class.is-invalid]="(hasError && productcategory_ID.touched)" (change)="validateType(productcategory_ID.value)">
<option value="default" selected>Select a Product Type</option>
<option *ngFor="let type of productTypes" value={{type.productcatergory_ID}}>{{type.productcatergory_NAME}}</option>
</select>
<small class="text-danger" *ngIf="hasError && productcategory_ID.touched">Please choose an appropriete type.</small>
</div>
<div class="form-group">
<label for="productimage_ID">Select an image:</label>
<input required type="file" accept=".jpg, .jpeg, .png" formControlName="productimage_ID" class="form-control" (change)="onFileSelected($event)">
</div>
<button class="btn btn-primary" type="submit">Insert product</button>
</form>
<!-- for button above [disabled]="insertProduct.invalid" -->
</div>
<!-- For displaying name of file.. -->
<script>
// Add the following code if you want the name of the file appear on select
$(".custom-file-input").on("change", function() {
var fileName = $(this).val().split("\\").pop();
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
});
</script>
使用文件输入注册的更改事件的打字稿代码是:
onFileSelected(event){
this.userFile=<File>event.target.File;
console.log(event);
console.log(this.userFile);
}
为了订阅服务,我使用以下代码向其发送表单数据:
onSubmit(){
const fd:FormData=new FormData();
fd.append('file', this.userFile);
console.log(this.insertProduct.value);
console.log(fd);
this.service.insertImage(fd)
.subscribe(
res=>console.log(res),
error=>console.log(error)
)
}
我在 Angular 中使用的服务类是:
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { Product } from './Interfaces/product';
@Injectable({
providedIn: 'root'
})
export class ProductService {
// headers = new HttpHeaders({'Access-Control-Allow-Origin' : '*'})
path: string="http://localhost:8080/productcategory";
productPath: string="http://localhost:8080/product";
constructor(private http: HttpClient) { }
//Posting image using form-data
insertImage(file: FormData){
var path=this.productPath+"/image";
return this.http.post(path, File)
.pipe(catchError(this.errorHandler));
}
}
现在我要提供我在 java spring 中调用的服务是:
// posting image in local path
@PostMapping("image")
public String saveFile(@RequestParam("file") MultipartFile file) throws IOException {
String directorypath = "E:\\Faltu Setup\\Tutorials\\Angular.JS Learning Path\\Youtube Tutorials\\Pratices(ANGULAR)\\Project\\src\\assets\\Images\\ItemIcons";
SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyy-hhmmss");
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
String fileName = "";
if (!file.isEmpty()) {
try {
String[] split = file.getOriginalFilename().split("\\.");
String ext = split[split.length - 1];
fileName = "File-" + dateFormat.format(date) + "." + ext;
log.info(file.getName());
log.info(file.getContentType());
log.info(file.getOriginalFilename());
log.info(fileName);
if (Files.notExists(Paths.get(directorypath), LinkOption.NOFOLLOW_LINKS)) {
Files.createDirectory(Paths.get(directorypath));
log.debug("I am entered.");
}
Files.copy(file.getInputStream(), Paths.get(directorypath + "/" + fileName));
} catch (IOException e) {
return mapper.writeValueAsString(e.getMessage());
}catch(RuntimeException e) {
return mapper.writeValueAsString(e.getMessage());
}
}
return mapper.writeValueAsString(fileName);
}
一切正常,现在你已经理解了我使用的所有代码,但是当我订阅它显示的服务时:
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:190) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:109) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.15.jar:8.5.15]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135) [na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.15.jar:8.5.15]
at java.base/java.lang.Thread.run(Thread.java:844) [na:na]
虽然它在浏览器的控制台中给出了以下相同的异常:
org.springframework.web.multipart.MultipartException
我尽力了,但无济于事。等待您的回复。 提前致谢。
【问题讨论】:
-
图片服务在/product下面,所以它调用的是正确的服务,所以你不用担心我在productpath下调用/image服务。
-
异常消息:
Current request is not a multipart request所以请检查您的表单并添加enctype="multipart/form-data"
标签: angular spring file-upload form-data