Java 使用Spring security和Rest web服务发送文件(大于小文件)时出现异常
我向Rest web服务(通过Spring创建)添加了基本身份验证,但对于成功使用的RestTemplate,我使用了以下类:Java 使用Spring security和Rest web服务发送文件(大于小文件)时出现异常,java,spring,rest,sockets,spring-security,Java,Spring,Rest,Sockets,Spring Security,我向Rest web服务(通过Spring创建)添加了基本身份验证,但对于成功使用的RestTemplate,我使用了以下类: public class RestClient extends RestTemplate { public RestClient(String username, String password) { CredentialsProvider credsProvider = new BasicCredentialsProvider();
public class RestClient extends RestTemplate {
public RestClient(String username, String password) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(null, -1),
new UsernamePasswordCredentials(username, password));
HttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
}
}
但是对于我的HttpPost
我使用的是:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(null,-1),
new UsernamePasswordCredentials(username, password));
try(CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).build()){
HttpPost httppost = new HttpPost(serverIp + "ATS/client/file");
File file = new File(filePath);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
ContentBody cbFile = new FileBody(file);
ContentBody cbPath= new StringBody(toStorePath,ContentType.TEXT_PLAIN);
builder.addPart("file", cbFile);
builder.addPart("toStorePath",cbPath);
httppost.setEntity(builder.build());
CloseableHttpResponse httpResponse = httpClient.execute(httppost);
HttpEntity resEntity = httpResponse.getEntity();
if (resEntity != null) {
ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue(resEntity.getContent(), Response.class);
EntityUtils.consume(resEntity) ;
return response;
}
//It should never be thrown
else return new Response(false, false, "Error with server response" , null);
}catch(Exception e){
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
return new Response(false, false,"Error sending the file!" , errorResponse);
}
但请求未到达服务器,因为客户端引发此异常:
INFO 11284 --- [nio-8080-exec-7] o.apache.http.impl.execchain.RetryExec : I/O exception (java.net.SocketException) caught when processing request to {}->http://localhost:8086: Connection reset by peer: socket write error
2015-12-23 12:49:45.815 INFO 11284 --- [nio-8080-exec-7] o.apache.http.impl.execchain.RetryExec : Retrying request to {}->http://localhost:8086
2015-12-23 12:49:46.818 INFO 11284 --- [nio-8080-exec-7] o.apache.http.impl.execchain.RetryExec : I/O exception (java.net.SocketException) caught when processing request to {}->http://localhost:8086: Connection reset by peer: socket write error
2015-12-23 12:49:46.818 INFO 11284 --- [nio-8080-exec-7] o.apache.http.impl.execchain.RetryExec : Retrying request to {}->http://localhost:8086
2015-12-23 12:49:47.821 INFO 11284 --- [nio-8080-exec-7] o.apache.http.impl.execchain.RetryExec : I/O exception (java.net.SocketException) caught when processing request to {}->http://localhost:8086: Connection reset by peer: socket write error
2015-12-23 12:49:47.821 INFO 11284 --- [nio-8080-exec-7] o.apache.http.impl.execchain.RetryExec : Retrying request to {}->http://localhost:8086
2015-12-23 12:49:48.825 ERROR 11284 --- [nio-8080-exec-7] client.controller.ErrorController : org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8086/ATS/client/file":Connection reset by peer: socket write error; nested exception is java.net.SocketException: Connection reset by peer: socket write error
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:580)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:330)
at client.services.FileServicesImpl.sendFile(FileServicesImpl.java:116)
at client.wbcontroller.ControllerMatlab.Write(ControllerMatlab.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:123)
at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:157)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:115)
at org.apache.http.entity.ByteArrayEntity.writeTo(ByteArrayEntity.java:112)
at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:155)
at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:149)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:236)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:91)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:569)
... 45 more
如果我使用一个非常小的文件,比如10Kb,所有的工作都是在线的,如果我用10MB的文件托盘接收异常
以下代码也存在相同的问题:
@Override
public Response sendFile(String username, String password, String serverIp, String toStorePath, String filePath) {
MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("file", new FileSystemResource(filePath));
mvm.add("toStorePath",toStorePath);
RestClient restClient = new RestClient(username, password);
return restClient.postForObject(serverIp + "ATS/client/file", mvm, Response.class);
如果我添加.antMatchers(“/client/file/**”).permitAll()(或者更确切地说,我添加了可验证性),它就可以工作了。
奇怪的是,在没有身份验证的情况下,我可以发送超过300MB的文件(我使用带有HTTPPOST的方法来使用流文件)。
我怎样才能修好它?使用这种方法,用户和密码是用https隐藏的吗?我已经花了两天时间了。谢谢如果是Web服务器过早关闭连接,那么您的服务器日志应该显示原因。此外,使用tcpdump/wireshark/etc记录网络流量可能会提示正在发生的事情。我使用所有stacktrace进行了更新。问题出在客户端,请求没有及时到达server@luca我也有同样的问题,你已经找到解决方案了吗?@esthrim如果我记得手动身份验证是有效的,因此,我从spring Security中排除了该路径,并使用特定的方法进行身份验证。
@Configuration
@Order(1)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/client/**")
.authorizeRequests().antMatchers("/client/file/**").permitAll()
//
.anyRequest().authenticated()
.and()
.httpBasic();
}
}