У меня есть специальный клиентский инструмент, который отправляет HTTP-запрос на мой серверный API RESTful.
Запрос может занять ~ 1 минуту (поскольку файлы загружаются в виде нескольких частей, как часть профиля пользователя).) и, возможно, клиентский процесс может быть прерван пользователем или окно терминала закрыто.В результате все файлы не загружаются.
Если клиентское средство уничтожено (разрывает соединение), java.io.IOException
отображается в журналах сервера, но выглядит так, как Exception
обрабатывается / используется контейнером (Использование WAS Liberty Profile).Когда это происходит, я хотел бы выполнить дополнительную обработку на стороне сервера, чтобы очистить неполный профиль.
Я пытаюсь использовать ExceptionMapper
для перехвата IOException
, но toResponse()
никогда не вызывается.Я что-то упустил?
MyApplication.java
:
package com.test.server;
import com.test.exceptions.IOExceptionMapper;
import com.test.server.Service;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class MyApplication extends Application {
@Override
public final Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MyService.class);
classes.add(MyApplication.class);
classes.add(IOExceptionMapper.class);
return classes;
}
}
MyService.java
:
package com.test.server;
@WebService
@Path("/")
public class MyService {
@POST
@Path("/profile")
@Produces(MediaType.TEXT_PLAIN)
public Response createProfile(@javax.ws.rs.core.Context final HttpHeaders httpHeaders,
@javax.ws.rs.core.Context final HttpServletRequest request) throws IOException {
// do things, duration is ~1 minute
ResponseBuilder rb = Response.status(Status.OK).entity("Created.");
return rb.build();
}
}
IOExceptionMapper.java
:
package com.test.exceptions;
import java.io.IOException;
import javax.inject.Singleton;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
@Singleton
public class IOExceptionMapper implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException ex) {
System.out.println("toResponse IOExceptionMapper");
return Response.status(404).entity(ex.getMessage()).type("text/plain").build();
}
}
Фрагмент из web.xml
:
<servlet>
<description>API</description>
<display-name>RESTAPI</display-name>
<servlet-name>RESTAPI</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.server.MyApplication</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.test.exceptions</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Журналы сервера:
[INFO ] FFDC1015I: An FFDC Incident has been created: "java.io.IOException: Connection closed: Read failed. Possible end of stream encountered. com.ibm.ws.webcontainer.security.PostParameterHelper 402" at ffdc_19.01.30_18.23.41.0.log
[INFO ] FFDC1015I: An FFDC Incident has been created: "java.io.IOException: Connection closed: Read failed. Possible end of stream encountered. com.ibm.wsspi.http.ee7.HttpInputStreamEE7 129" at ffdc_19.01.30_18.23.41.1.log
[INFO ] FFDC1015I: An FFDC Incident has been created: "java.io.IOException: SRVE0216E: post body contains less bytes than specified by content-length. com.ibm.ws.webcontainer.security.PostParameterHelper 402" at ffdc_19.01.30_18.23.41.2.log
[INFO ] FFDC1015I: An FFDC Incident has been created: "java.io.IOException: Connection closed: Read failed. Possible end of stream encountered. org.apache.cxf.transport.http.AbstractHTTPDestination$BackChannelConduit 786" at ffdc_19.01.30_18.23.45.0.log
[INFO ] FFDC1015I: An FFDC Incident has been created: "java.io.IOException: Connection closed: Read failed. Possible end of stream encountered. com.ibm.ws.webcontainer.srt.SRTServletRequest.finish 875" at ffdc_19.01.30_18.23.45.1.log