Skip to content

Commit da238a8

Browse files
committed
Allowing sending Status over sending error
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
1 parent 21668db commit da238a8

File tree

6 files changed

+193
-7
lines changed

6 files changed

+193
-7
lines changed

core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java

+19-6
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ public class ServerRuntime {
130130
/** Resolve relative URIs according to RFC7231 (not JAX-RS 2.0 compliant */
131131
private final boolean rfc7231LocationHeaderRelativeUriResolution;
132132

133+
/**
134+
* Cached value of configuration property
135+
* {@link org.glassfish.jersey.server.ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR}.
136+
* If {@code true} method {@link ServerRuntime.CompletionCallbackRunner#onComplete(Throwable)}
137+
* is used over {@link DefaultExceptionMapper#toResponse(Throwable)}.
138+
*/
139+
private final boolean configSetStatusOverSendError;
140+
133141
/**
134142
* Default exception mapper (@since 3.1.0 according to JAX-RS 3.1 spec)
135143
*/
@@ -197,6 +205,9 @@ private ServerRuntime(final Stage<RequestProcessingContext> requestProcessingRoo
197205
this.rfc7231LocationHeaderRelativeUriResolution = ServerProperties.getValue(configuration.getProperties(),
198206
ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231,
199207
Boolean.FALSE, Boolean.class);
208+
209+
this.configSetStatusOverSendError = ServerProperties.getValue(configuration.getProperties(),
210+
ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, false, Boolean.class);
200211
}
201212

202213
/**
@@ -452,15 +463,17 @@ public void process(final Throwable throwable) {
452463

453464
if (!processResponseError(responseError)) {
454465
// Pass the exception to the container.
455-
LOGGER.log(Level.WARNING, LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER(), responseError);
456-
457466
try {
458467
request.getResponseWriter().failure(responseError);
459468
} finally {
460-
defaultMapperResponse = processResponseWithDefaultExceptionMapper(responseError, request);
461-
462-
// completionCallbackRunner.onComplete(responseError); is called from
463-
// processResponseWithDefaultExceptionMapper
469+
if (runtime.configSetStatusOverSendError) {
470+
completionCallbackRunner.onComplete(responseError);
471+
} else {
472+
LOGGER.log(Level.WARNING,
473+
LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER(),
474+
responseError);
475+
defaultMapperResponse = processResponseWithDefaultExceptionMapper(responseError, request);
476+
}
464477
}
465478

466479
}

tests/integration/servlet-tests/pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<dependency>
4949
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
5050
<artifactId>jersey-test-framework-provider-external</artifactId>
51+
<scope>test</scope>
5152
</dependency>
5253
</dependencies>
5354

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.tests.integration.servlettests;
18+
19+
import jakarta.servlet.Filter;
20+
import jakarta.servlet.FilterChain;
21+
import jakarta.servlet.FilterConfig;
22+
import jakarta.servlet.ServletException;
23+
import jakarta.servlet.ServletRequest;
24+
import jakarta.servlet.ServletResponse;
25+
26+
import java.io.IOException;
27+
28+
import static org.glassfish.jersey.tests.integration.servlettests.PostProcessingErrorResource.ERROR_MESSAGE;
29+
30+
public class PostProcessingErrorFilter implements Filter {
31+
@Override
32+
public void init(FilterConfig filterConfig) throws ServletException {
33+
Filter.super.init(filterConfig);
34+
}
35+
36+
@Override
37+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
38+
throws IOException {
39+
40+
try {
41+
chain.doFilter(request, response);
42+
} catch (ServletException ex) {
43+
//post-processing attempt
44+
final Throwable orig = ex.getRootCause();
45+
if (orig.getMessage().equalsIgnoreCase(ERROR_MESSAGE)) {
46+
response.getWriter().print(ERROR_MESSAGE);
47+
response.getWriter().flush();
48+
}
49+
}
50+
}
51+
52+
@Override
53+
public void destroy() {
54+
Filter.super.destroy();
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.tests.integration.servlettests;
18+
19+
import jakarta.servlet.http.HttpServlet;
20+
import jakarta.ws.rs.GET;
21+
import jakarta.ws.rs.Path;
22+
import jakarta.ws.rs.ProcessingException;
23+
import jakarta.ws.rs.core.Response;
24+
25+
@Path("postprocessing")
26+
public class PostProcessingErrorResource extends HttpServlet {
27+
28+
static final String ERROR_MESSAGE = "Must be post processed";
29+
@GET
30+
public Response getException() {
31+
throw new ProcessingException(ERROR_MESSAGE);
32+
}
33+
34+
}

tests/integration/servlet-tests/src/main/webapp/WEB-INF/web.xml

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
4+
Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
55
66
This program and the accompanying materials are made available under the
77
terms of the Eclipse Public License v. 2.0, which is available at
@@ -157,4 +157,31 @@
157157
<filter-name>custom404</filter-name>
158158
<url-pattern>/custom404/*</url-pattern>
159159
</filter-mapping>
160+
161+
<!-- post process errors (40*, 50*) -->
162+
<filter>
163+
<filter-name>PostProcessFilter</filter-name>
164+
<filter-class>org.glassfish.jersey.tests.integration.servlettests.PostProcessingErrorFilter</filter-class>
165+
</filter>
166+
<servlet>
167+
<servlet-name>PostProcessServlet</servlet-name>
168+
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
169+
<init-param>
170+
<param-name>jersey.config.server.provider.classnames</param-name>
171+
<param-value>org.glassfish.jersey.tests.integration.servlettests.PostProcessingErrorResource</param-value>
172+
</init-param>
173+
<init-param>
174+
<param-name>jersey.config.server.response.setStatusOverSendError</param-name>
175+
<param-value>true</param-value>
176+
</init-param>
177+
<load-on-startup>1</load-on-startup>
178+
</servlet>
179+
<servlet-mapping>
180+
<servlet-name>PostProcessServlet</servlet-name>
181+
<url-pattern>/postProcess/*</url-pattern>
182+
</servlet-mapping>
183+
<filter-mapping>
184+
<filter-name>PostProcessFilter</filter-name>
185+
<url-pattern>/postProcess/*</url-pattern>
186+
</filter-mapping>
160187
</web-app>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.tests.integration.servlettests;
18+
19+
import jakarta.ws.rs.core.Application;
20+
import jakarta.ws.rs.core.Response;
21+
import org.glassfish.jersey.server.ResourceConfig;
22+
import org.glassfish.jersey.server.ServerProperties;
23+
import org.glassfish.jersey.test.JerseyTest;
24+
import org.glassfish.jersey.test.external.ExternalTestContainerFactory;
25+
import org.glassfish.jersey.test.spi.TestContainerException;
26+
import org.glassfish.jersey.test.spi.TestContainerFactory;
27+
import org.junit.jupiter.api.Test;
28+
29+
import java.util.Locale;
30+
31+
import static org.glassfish.jersey.tests.integration.servlettests.PostProcessingErrorResource.ERROR_MESSAGE;
32+
import static org.junit.jupiter.api.Assertions.assertEquals;
33+
34+
public class PostProcesingITCase extends JerseyTest {
35+
36+
@Override
37+
protected Application configure() {
38+
// dummy resource config
39+
return new ResourceConfig();
40+
}
41+
42+
@Override
43+
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
44+
return new ExternalTestContainerFactory();
45+
}
46+
47+
@Test
48+
public void testPostProcessingLocale() {
49+
final Response response = target()
50+
.path("postProcess/postprocessing")
51+
.request().get();
52+
assertEquals(ERROR_MESSAGE, response.readEntity(String.class));
53+
}
54+
55+
}

0 commit comments

Comments
 (0)