This is an automated email from the ASF dual-hosted git repository.

jacopoc pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 1b2aa9dfe Improved: various non-functional improvements to code and 
organization for the rest-api plugin.
1b2aa9dfe is described below

commit 1b2aa9dfea64719778e3350924e131fc5e42734b
Author: Jacopo Cappellato <[email protected]>
AuthorDate: Mon Nov 10 15:08:23 2025 +0100

    Improved: various non-functional improvements to code and organization for 
the rest-api plugin.
    
    Simplified error and response handling.
    Simplified internal class structure by leveraging @context annotation for 
ServletContext.
    Fixed and cleaned up various classes in order to properly use annotations.
    Grouped together all custom annotations under the same custom package.
    Various code cleanups.
    
    Thanks: to Deepak Dixit for the help with the review and update to the 
latest version of the plugin.
---
 .../org/apache/ofbiz/ws/rs/ConflictException.java  | 38 ---------
 .../ofbiz/ws/rs/ServiceRequestProcessor.java       |  5 +-
 .../ws/rs/{security => annotation}/AuthToken.java  |  2 +-
 .../ws/rs/{security => annotation}/Secured.java    |  2 +-
 .../apache/ofbiz/ws/rs/core/OFBizApiConfig.java    |  2 +-
 .../ofbiz/ws/rs/listener/ApiContextListener.java   | 11 +--
 .../ofbiz/ws/rs/process/ServiceRequestHandler.java |  3 +-
 .../ws/rs/resources/AuthenticationResource.java    | 36 +++++----
 .../ofbiz/ws/rs/resources/IOFBizResource.java      | 44 -----------
 .../ofbiz/ws/rs/resources/OFBizResource.java       | 41 ----------
 .../ws/rs/resources/OFBizServiceResource.java      | 27 ++++---
 .../org/apache/ofbiz/ws/rs/response/Messages.java  | 62 ---------------
 .../org/apache/ofbiz/ws/rs/response/Response.java  | 91 ----------------------
 .../ofbiz/ws/rs/security/auth/APIAuthFilter.java   |  6 +-
 .../ws/rs/security/auth/HttpBasicAuthFilter.java   |  2 +-
 .../ofbiz/ws/rs/spi/AbstractExceptionMapper.java   | 71 -----------------
 .../rs/spi/impl/GenericServiceExceptionMapper.java | 13 ++--
 .../ws/rs/spi/impl/GlobalExceptionMapper.java      | 12 ++-
 .../spi/impl/JsonifiedParamConverterProvider.java  |  1 +
 .../org/apache/ofbiz/ws/rs/util/ErrorUtil.java     | 75 ------------------
 .../org/apache/ofbiz/ws/rs/util/RestApiUtil.java   | 43 ++++++++--
 21 files changed, 107 insertions(+), 480 deletions(-)

diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ConflictException.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ConflictException.java
deleted file mode 100644
index 830172867..000000000
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ConflictException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-package org.apache.ofbiz.ws.rs;
-
-import jakarta.ws.rs.WebApplicationException;
-import jakarta.ws.rs.core.Response;
-
-/**
- * A HTTP 409 (Conflict) exception
- */
-public class ConflictException extends WebApplicationException {
-
-    private static final long serialVersionUID = -3002310435429546325L;
-
-    /**
-     * Construct a new ConflictException exception.
-     */
-    public ConflictException(String message) {
-        super(message, Response.Status.CONFLICT);
-    }
-
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
index 946f34fb9..9807fd290 100644
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
+++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
@@ -34,7 +34,6 @@ import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ModelParam;
 import org.apache.ofbiz.service.ModelService;
 import org.apache.ofbiz.service.ServiceUtil;
-import org.apache.ofbiz.ws.rs.util.ErrorUtil;
 import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 
 public class ServiceRequestProcessor {
@@ -65,8 +64,8 @@ public class ServiceRequestProcessor {
         Map<String, Object> serviceContext = 
dispatchContext.makeValidContext(serviceName, ModelService.IN_PARAM, 
requestMap);
         serviceContext.put("userLogin", userLogin);
         Map<String, Object> result = dispatcher.runSync(serviceName, 
serviceContext);
-        Map<String, Object> responseData = new LinkedHashMap<>();
         if (ServiceUtil.isSuccess(result)) {
+            Map<String, Object> responseData = new LinkedHashMap<>();
             Set<String> outParams = service.getOutParamNames();
             for (String outParamName : outParams) {
                 ModelParam outParam = service.getParam(outParamName);
@@ -79,7 +78,7 @@ public class ServiceRequestProcessor {
             }
             return RestApiUtil.success((String) 
result.get(ModelService.SUCCESS_MESSAGE), responseData);
         } else {
-            return ErrorUtil.buildErrorFromServiceResult(serviceName, result, 
request.getLocale());
+            return RestApiUtil.buildErrorFromServiceResult(serviceName, 
result, request.getLocale());
         }
     }
 }
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/AuthToken.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/annotation/AuthToken.java
similarity index 96%
rename from 
rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/AuthToken.java
rename to 
rest-api/src/main/java/org/apache/ofbiz/ws/rs/annotation/AuthToken.java
index 2493bb5fb..656c8376d 100644
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/AuthToken.java
+++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/annotation/AuthToken.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.security;
+package org.apache.ofbiz.ws.rs.annotation;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/Secured.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/annotation/Secured.java
similarity index 96%
rename from rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/Secured.java
rename to rest-api/src/main/java/org/apache/ofbiz/ws/rs/annotation/Secured.java
index e7edf4d52..456c89f4d 100644
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/Secured.java
+++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/annotation/Secured.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.security;
+package org.apache.ofbiz.ws.rs.annotation;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
index 524c58801..edbbdb89a 100644
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
+++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
@@ -38,7 +38,7 @@ import org.apache.ofbiz.ws.rs.model.ModelApiReader;
 import org.apache.ofbiz.ws.rs.model.ModelOperation;
 import org.apache.ofbiz.ws.rs.model.ModelResource;
 import org.apache.ofbiz.ws.rs.process.ServiceRequestHandler;
-import org.apache.ofbiz.ws.rs.security.Secured;
+import org.apache.ofbiz.ws.rs.annotation.Secured;
 import org.glassfish.jersey.jackson.JacksonFeature;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/listener/ApiContextListener.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/listener/ApiContextListener.java
index 3fad9af55..70a9f8472 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/listener/ApiContextListener.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/listener/ApiContextListener.java
@@ -24,24 +24,25 @@ import jakarta.servlet.ServletContextListener;
 
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.entity.Delegator;
+import org.apache.ofbiz.entity.DelegatorFactory;
 import org.apache.ofbiz.service.LocalDispatcher;
-import org.apache.ofbiz.webapp.WebAppUtil;
+import org.apache.ofbiz.service.ServiceContainer;
 
 public class ApiContextListener implements ServletContextListener {
 
     public static final String MODULE = ApiContextListener.class.getName();
+    // TODO: remove after the refactoring of OFBizOpenApiReader
     private static ServletContext servletContext = null;
 
     /**
      */
     public void contextInitialized(ServletContextEvent sce) {
         servletContext = sce.getServletContext();
-        Delegator delegator = WebAppUtil.getDelegator(servletContext);
-        LocalDispatcher dispatcher = WebAppUtil.getDispatcher(servletContext);
+        Delegator delegator = 
DelegatorFactory.getDelegator(servletContext.getInitParameter("entityDelegatorName"));
+        LocalDispatcher dispatcher = 
ServiceContainer.getLocalDispatcher(servletContext.getInitParameter("localDispatcherName"),
 delegator);
         Debug.logInfo("Api Jersey Context initialized, delegator " + delegator 
+ ", dispatcher", MODULE);
         servletContext.setAttribute("delegator", delegator);
         servletContext.setAttribute("dispatcher", dispatcher);
-        servletContext.setAttribute("security", 
WebAppUtil.getSecurity(servletContext));
     }
 
     /**
@@ -51,10 +52,10 @@ public class ApiContextListener implements 
ServletContextListener {
         Debug.logInfo("Api Jersey Context destroyed, removing delegator and 
dispatcher ", MODULE);
         context.removeAttribute("delegator");
         context.removeAttribute("dispatcher");
-        context.removeAttribute("security");
         context = null;
     }
 
+    // TODO: remove after the refactoring of OFBizOpenApiReader
     public static ServletContext getApplicationCntx() {
         return servletContext;
     }
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java
index b67bd742e..c3b57226d 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java
@@ -36,7 +36,6 @@ import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ModelParam;
 import org.apache.ofbiz.service.ModelService;
 import org.apache.ofbiz.service.ServiceUtil;
-import org.apache.ofbiz.ws.rs.util.ErrorUtil;
 import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 import org.apache.ofbiz.ws.rs.ServiceNameContextHolder;
 
@@ -91,7 +90,7 @@ public final class ServiceRequestHandler extends 
RestRequestHandler {
             }
             return RestApiUtil.success((String) 
result.get(ModelService.SUCCESS_MESSAGE), responseData);
         } else {
-            return ErrorUtil.buildErrorFromServiceResult(service, result, 
getHttpRequest().getLocale());
+            return RestApiUtil.buildErrorFromServiceResult(service, result, 
getHttpRequest().getLocale());
         }
     }
 
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
index ed5f314af..accf70823 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
@@ -20,6 +20,7 @@ package org.apache.ofbiz.ws.rs.resources;
 
 import java.util.Map;
 
+import jakarta.servlet.ServletContext;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.ws.rs.HeaderParam;
@@ -30,13 +31,13 @@ import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.Provider;
 
 import org.apache.ofbiz.base.util.UtilMisc;
+import org.apache.ofbiz.entity.Delegator;
 import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.entity.util.EntityUtilProperties;
 import org.apache.ofbiz.webapp.control.JWTManager;
-import org.apache.ofbiz.ws.rs.security.AuthToken;
+import org.apache.ofbiz.ws.rs.annotation.AuthToken;
 import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 
 import io.swagger.v3.oas.annotations.Operation;
@@ -47,9 +48,11 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 
 
 @Path("/auth")
-@Provider
 @Tag(name = "Authentication Token Generating Resource", description = 
"Intended to provide generation of authentication tokens.")
-public class AuthenticationResource extends OFBizResource {
+public class AuthenticationResource {
+
+    @Context
+    private ServletContext servletContext;
 
     @Context
     private HttpServletRequest httpRequest;
@@ -68,15 +71,17 @@ public class AuthenticationResource extends OFBizResource {
     public Response getAuthToken(@Parameter(in = ParameterIn.HEADER, name = 
"Authorization",
             description = "Authorization header using Basic Authentication", 
example = HttpHeaders.AUTHORIZATION + ": Basic YWRtaW46b2ZiaXo=")
             @HeaderParam(HttpHeaders.AUTHORIZATION) String creds) {
-        httpRequest.setAttribute("delegator", getDelegator());
-        httpRequest.setAttribute("dispatcher", getDispatcher());
+        Delegator delegator = (Delegator) 
servletContext.getAttribute("delegator");
+        httpRequest.setAttribute("delegator", delegator);
+        httpRequest.setAttribute("dispatcher", 
servletContext.getAttribute("dispatcher"));
         GenericValue userLogin = (GenericValue) 
httpRequest.getAttribute("userLogin");
         //TODO : Move this into an OFBiz service. All such implementations 
should be inside an OFBiz service.
-        String jwtToken = JWTManager.createJwt(getDelegator(), 
UtilMisc.toMap("userLoginId", userLogin.getString("userLoginId")));
-        String refreshToken = JWTManager.createRefreshToken(getDelegator(), 
userLogin.getString("userLoginId"));
+        String jwtToken = JWTManager.createJwt(delegator,
+                UtilMisc.toMap("userLoginId", 
userLogin.getString("userLoginId")));
+        String refreshToken = JWTManager.createRefreshToken(delegator, 
userLogin.getString("userLoginId"));
 
         Map<String, Object> tokenPayload = UtilMisc.toMap("access_token", 
jwtToken, "refresh_token", refreshToken,
-                "expires_in", 
EntityUtilProperties.getPropertyValue("security", 
"security.jwt.token.expireTime", "1800", getDelegator()),
+                "expires_in", 
EntityUtilProperties.getPropertyValue("security", 
"security.jwt.token.expireTime", "1800", delegator),
                 "token_type", "Bearer");
         return RestApiUtil.success("Token granted.", tokenPayload);
     }
@@ -97,9 +102,10 @@ public class AuthenticationResource extends OFBizResource {
     @Operation(description = "Generates a new access token using a refresh 
token.")
     public Response refreshToken(@HeaderParam("Refresh-Token") String 
refreshToken) {
 
-        httpRequest.setAttribute("delegator", getDelegator());
-        httpRequest.setAttribute("dispatcher", getDispatcher());
-        Map<String, Object> claims = 
JWTManager.validateRefreshToken(refreshToken, 
JWTManager.getJWTKey(getDelegator()));
+        Delegator delegator = (Delegator) 
servletContext.getAttribute("delegator");
+        httpRequest.setAttribute("delegator", delegator);
+        httpRequest.setAttribute("dispatcher", delegator);
+        Map<String, Object> claims = 
JWTManager.validateRefreshToken(refreshToken, JWTManager.getJWTKey(delegator));
 
         // Fetch delegator, dispatcher, and userLogin
         if (claims.containsKey("errorMessage")) {
@@ -108,11 +114,11 @@ public class AuthenticationResource extends OFBizResource 
{
 
         String userLoginId = (String) claims.get("userLoginId");
 
-        String newAccessToken = JWTManager.createJwt(getDelegator(), 
UtilMisc.toMap("userLoginId", userLoginId));
-        String newRefreshToken = JWTManager.createRefreshToken(getDelegator(), 
userLoginId);
+        String newAccessToken = JWTManager.createJwt(delegator, 
UtilMisc.toMap("userLoginId", userLoginId));
+        String newRefreshToken = JWTManager.createRefreshToken(delegator, 
userLoginId);
 
         Map<String, Object> tokenPayload = UtilMisc.toMap("access_token", 
newAccessToken, "refresh_token", newRefreshToken, "expires_in",
-                EntityUtilProperties.getPropertyValue("security", 
"security.jwt.token.expireTime", "1800", getDelegator()), "token_type", 
"Bearer");
+                EntityUtilProperties.getPropertyValue("security", 
"security.jwt.token.expireTime", "1800", delegator), "token_type", "Bearer");
 
         return RestApiUtil.success("Token refreshed.", tokenPayload);
     }
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/IOFBizResource.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/IOFBizResource.java
deleted file mode 100644
index 51625388d..000000000
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/IOFBizResource.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.resources;
-
-import jakarta.ws.rs.ext.Provider;
-
-import org.apache.ofbiz.entity.Delegator;
-import org.apache.ofbiz.service.LocalDispatcher;
-import org.apache.ofbiz.webapp.WebAppUtil;
-import org.apache.ofbiz.ws.rs.listener.ApiContextListener;
-
-/**
- * Resource Interface
- */
-@Provider
-public interface IOFBizResource {
-
-    default Delegator getDelegator() {
-        Delegator delegator = 
WebAppUtil.getDelegator(ApiContextListener.getApplicationCntx());
-        return delegator;
-    }
-
-    default LocalDispatcher getDispatcher() {
-        LocalDispatcher dispatcher = 
WebAppUtil.getDispatcher(ApiContextListener.getApplicationCntx());
-        return dispatcher;
-    }
-
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizResource.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizResource.java
deleted file mode 100644
index c4f70c563..000000000
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizResource.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.resources;
-
-import jakarta.servlet.ServletContext;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.ext.Provider;
-
-import org.apache.ofbiz.entity.Delegator;
-import org.apache.ofbiz.service.LocalDispatcher;
-
-/**
- *
- */
-@Provider
-public abstract class OFBizResource implements IOFBizResource {
-
-    @Context
-    private ServletContext servletContext;
-
-    private Delegator delegator = getDelegator();
-
-    private LocalDispatcher dispatcher = getDispatcher();
-
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
index 50bfe1399..7c24a5817 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
@@ -26,8 +26,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import jakarta.servlet.ServletContext;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.ws.rs.BadRequestException;
+import jakarta.ws.rs.Consumes;
 import jakarta.ws.rs.DELETE;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.HttpMethod;
@@ -43,7 +45,6 @@ import jakarta.ws.rs.core.Link;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.UriInfo;
-import jakarta.ws.rs.ext.Provider;
 
 import org.apache.ofbiz.base.util.UtilMisc;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -54,18 +55,20 @@ import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ModelService;
 import org.apache.ofbiz.ws.rs.ApiServiceRequest;
 import org.apache.ofbiz.ws.rs.ServiceRequestProcessor;
+import org.apache.ofbiz.ws.rs.annotation.Secured;
 import org.apache.ofbiz.ws.rs.annotation.ServiceRequestValidator;
 import org.apache.ofbiz.ws.rs.response.Success;
-import org.apache.ofbiz.ws.rs.security.Secured;
 
 @Secured
 @Path(OFBizServiceResource.BASE_PATH)
-@Provider
 @ServiceRequestValidator
-public class OFBizServiceResource extends OFBizResource {
+public class OFBizServiceResource {
 
     public static final String BASE_PATH = "/services";
 
+    @Context
+    private ServletContext servletContext;
+
     @Context
     private UriInfo uriInfo;
 
@@ -79,7 +82,7 @@ public class OFBizServiceResource extends OFBizResource {
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public Response serviceList() throws GenericServiceException {
-        LocalDispatcher dispatcher = getDispatcher();
+        LocalDispatcher dispatcher = (LocalDispatcher) 
servletContext.getAttribute("dispatcher");
         DispatchContext context = dispatcher.getDispatchContext();
         Set<String> serviceNames = context.getAllServiceNames();
         List<Map<String, Object>> serviceList = new ArrayList<>();
@@ -115,7 +118,7 @@ public class OFBizServiceResource extends OFBizResource {
             @PathParam(value = "serviceName") String serviceName) throws 
IOException, GenericServiceException {
         ServiceRequestProcessor processor = new ServiceRequestProcessor();
         return processor.process(UtilMisc.toMap("serviceName", serviceName, 
"httpVerb", HttpMethod.GET, "requestMap",
-                serviceRequest.getInParams(), "dispatcher", getDispatcher(), 
"request", httpRequest));
+                serviceRequest.getInParams(), "dispatcher", 
servletContext.getAttribute("dispatcher"), "request", httpRequest));
     }
 
     /**
@@ -128,6 +131,7 @@ public class OFBizServiceResource extends OFBizResource {
      */
     @POST
     @Path("/{serviceName}")
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response doPost(HashMap<String, Object> serviceInParams,
             @PathParam(value = "serviceName") String serviceName)
@@ -137,7 +141,7 @@ public class OFBizServiceResource extends OFBizResource {
         }
         ServiceRequestProcessor processor = new ServiceRequestProcessor();
         return processor.process(UtilMisc.toMap("serviceName", serviceName, 
"httpVerb", HttpMethod.POST, "requestMap",
-                serviceInParams, "dispatcher", getDispatcher(), "request", 
httpRequest));
+                serviceInParams, "dispatcher", 
servletContext.getAttribute("dispatcher"), "request", httpRequest));
     }
 
     /**
@@ -150,6 +154,7 @@ public class OFBizServiceResource extends OFBizResource {
      */
     @PUT
     @Path("/{serviceName}")
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response doPut(HashMap<String, Object> serviceInParams, 
@PathParam(value = "serviceName") String serviceName)
             throws IOException, GenericEntityException, 
GenericServiceException {
@@ -158,7 +163,7 @@ public class OFBizServiceResource extends OFBizResource {
         }
         ServiceRequestProcessor processor = new ServiceRequestProcessor();
         return processor.process(UtilMisc.toMap("serviceName", serviceName, 
"httpVerb", HttpMethod.PUT, "requestMap",
-                serviceInParams, "dispatcher", getDispatcher(), "request", 
httpRequest));
+                serviceInParams, "dispatcher", 
servletContext.getAttribute("dispatcher"), "request", httpRequest));
     }
 
     /**
@@ -171,6 +176,7 @@ public class OFBizServiceResource extends OFBizResource {
      */
     @PATCH
     @Path("/{serviceName}")
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response doPatch(HashMap<String, Object> serviceInParams,
             @PathParam(value = "serviceName") String serviceName)
@@ -180,7 +186,7 @@ public class OFBizServiceResource extends OFBizResource {
         }
         ServiceRequestProcessor processor = new ServiceRequestProcessor();
         return processor.process(UtilMisc.toMap("serviceName", serviceName, 
"httpVerb", HttpMethod.PATCH, "requestMap",
-                serviceInParams, "dispatcher", getDispatcher(), "request", 
httpRequest));
+                serviceInParams, "dispatcher", 
servletContext.getAttribute("dispatcher"), "request", httpRequest));
     }
 
     /**
@@ -193,6 +199,7 @@ public class OFBizServiceResource extends OFBizResource {
      */
     @DELETE
     @Path("/{serviceName}")
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response doDelete(HashMap<String, Object> serviceInParams,
             @PathParam(value = "serviceName") String serviceName)
@@ -202,6 +209,6 @@ public class OFBizServiceResource extends OFBizResource {
         }
         ServiceRequestProcessor processor = new ServiceRequestProcessor();
         return processor.process(UtilMisc.toMap("serviceName", serviceName, 
"httpVerb", HttpMethod.DELETE, "requestMap",
-                serviceInParams, "dispatcher", getDispatcher(), "request", 
httpRequest));
+                serviceInParams, "dispatcher", 
servletContext.getAttribute("dispatcher"), "request", httpRequest));
     }
 }
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/response/Messages.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/response/Messages.java
deleted file mode 100644
index dd607ceb3..000000000
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/response/Messages.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.response;
-
-public class Messages {
-
-    private String successMsgKey;
-    private String errorMsgKey;
-
-    public Messages(String successMessageVal, String errorMessageVal) {
-        successMsgKey = successMessageVal;
-        errorMsgKey = errorMessageVal;
-    }
-
-    /**
-     * @param successKey
-     * @return
-     */
-    public Messages successKey(String successKey) {
-        successMsgKey = successKey;
-        return this;
-    }
-
-    /**
-     * @param errorKey
-     * @return
-     */
-    public Messages errorKey(String errorKey) {
-        errorMsgKey = errorKey;
-        return this;
-    }
-
-    /**
-     * @return the successMsgKey
-     */
-    public String getSuccessMsgKey() {
-        return successMsgKey;
-    }
-
-    /**
-     * @return the errorMsgKey
-     */
-    public String getErrorMsgKey() {
-        return errorMsgKey;
-    }
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/response/Response.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/response/Response.java
deleted file mode 100644
index f513eca05..000000000
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/response/Response.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.response;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-@JsonPropertyOrder({ "statusCode", "statusDescription", "data", "error" })
-@JsonInclude(Include.NON_NULL)
-public class Response {
-    private int statusCode;
-    private String statusDescription;
-    @JsonProperty("payload")
-    private Success success;
-    private Error error;
-
-    /**
-     * @return the statusCode
-     */
-    public int getStatusCode() {
-        return statusCode;
-    }
-
-    /**
-     * @param statusCode the statusCode to set
-     */
-    public void setStatusCode(int statusCode) {
-        this.statusCode = statusCode;
-    }
-
-    /**
-     * @return the statusDescription
-     */
-    public String getStatusDescription() {
-        return statusDescription;
-    }
-
-    /**
-     * @param statusDescription the statusDescription to set
-     */
-    public void setStatusDescription(String statusDescription) {
-        this.statusDescription = statusDescription;
-    }
-
-    /**
-     * @return the success
-     */
-    public Success getSuccess() {
-        return success;
-    }
-
-    /**
-     * @param success the success to set
-     */
-    public void setSuccess(Success success) {
-        this.success = success;
-    }
-
-    /**
-     * @return the error
-     */
-    public Error getError() {
-        return error;
-    }
-
-    /**
-     * @param error the error to set
-     */
-    public void setError(Error error) {
-        this.error = error;
-    }
-
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/APIAuthFilter.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/APIAuthFilter.java
index f5c64c47f..2260f1f1c 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/APIAuthFilter.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/APIAuthFilter.java
@@ -41,12 +41,12 @@ import org.apache.ofbiz.entity.GenericEntityException;
 import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.entity.util.EntityQuery;
 import org.apache.ofbiz.service.GenericServiceException;
+import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ModelService;
-import org.apache.ofbiz.webapp.WebAppUtil;
 import org.apache.ofbiz.webapp.control.JWTManager;
+import org.apache.ofbiz.ws.rs.annotation.Secured;
 import org.apache.ofbiz.ws.rs.common.AuthenticationScheme;
 import org.apache.ofbiz.ws.rs.resources.OFBizServiceResource;
-import org.apache.ofbiz.ws.rs.security.Secured;
 import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 
 /**
@@ -81,7 +81,7 @@ public class APIAuthFilter implements ContainerRequestFilter {
             if (UtilValidate.isNotEmpty(service)) {
                 ModelService mdService = null;
                 try {
-                    mdService = 
WebAppUtil.getDispatcher(servletContext).getDispatchContext().getModelService(service);
+                    mdService = ((LocalDispatcher) 
servletContext.getAttribute("dispatcher")).getDispatchContext().getModelService(service);
                 } catch (GenericServiceException e) {
                     Debug.logError(e.getMessage(), MODULE);
                 }
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/HttpBasicAuthFilter.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/HttpBasicAuthFilter.java
index 498cf76e5..27b6b14ed 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/HttpBasicAuthFilter.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/security/auth/HttpBasicAuthFilter.java
@@ -40,8 +40,8 @@ import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.service.GenericServiceException;
 import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ServiceUtil;
+import org.apache.ofbiz.ws.rs.annotation.AuthToken;
 import org.apache.ofbiz.ws.rs.common.AuthenticationScheme;
-import org.apache.ofbiz.ws.rs.security.AuthToken;
 import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 
 
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/AbstractExceptionMapper.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/AbstractExceptionMapper.java
deleted file mode 100644
index c88bc901e..000000000
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/AbstractExceptionMapper.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-package org.apache.ofbiz.ws.rs.spi;
-
-import jakarta.ws.rs.WebApplicationException;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-
-import org.apache.ofbiz.ws.rs.response.Error;
-
-/*
- *
- */
-public class AbstractExceptionMapper {
-    /**
-     * @param status
-     * @param responseEntity
-     * @return
-     */
-    protected Response errorResponse(int status, Error responseEntity) {
-        return customizeResponse(status, responseEntity);
-    }
-
-    /**
-     * @param status
-     * @param responseEntity
-     * @param t
-     * @return
-     */
-    protected Response errorResponse(int status, Error responseEntity, 
Throwable t) {
-        return customizeResponse(status, responseEntity);
-    }
-
-    /**
-     * @param ex
-     * @return
-     */
-    protected Response.StatusType getStatusType(Throwable ex) {
-        if (ex instanceof WebApplicationException) {
-            return ((WebApplicationException) 
ex).getResponse().getStatusInfo();
-        } else {
-            return Response.Status.INTERNAL_SERVER_ERROR;
-        }
-    }
-
-    /**
-     * @param status
-     * @param responseEntity
-     * @return
-     */
-    private Response customizeResponse(int status, Error responseEntity) {
-        return 
Response.status(status).entity(responseEntity).type(MediaType.APPLICATION_JSON).build();
-    }
-
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java
index a2bbc2963..1e61b458a 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java
@@ -34,8 +34,7 @@ import org.apache.ofbiz.service.GenericServiceException;
 import org.apache.ofbiz.service.ServiceValidationException;
 import org.apache.ofbiz.ws.rs.core.ResponseStatus;
 import org.apache.ofbiz.ws.rs.response.Error;
-import org.apache.ofbiz.ws.rs.spi.AbstractExceptionMapper;
-import org.apache.ofbiz.ws.rs.util.ErrorUtil;
+import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 import org.codehaus.groovy.runtime.InvokerInvocationException;
 import org.apache.ofbiz.ws.rs.ServiceNameContextHolder;
 
@@ -45,7 +44,7 @@ import org.apache.ofbiz.ws.rs.ServiceNameContextHolder;
  *
  */
 @Provider
-public class GenericServiceExceptionMapper extends AbstractExceptionMapper 
implements jakarta.ws.rs.ext.ExceptionMapper<GenericServiceException> {
+public class GenericServiceExceptionMapper implements 
jakarta.ws.rs.ext.ExceptionMapper<GenericServiceException> {
 
     /**
      * Module Name Used for debugging
@@ -79,7 +78,7 @@ public class GenericServiceExceptionMapper extends 
AbstractExceptionMapper imple
             Error error = new 
Error().type(actualCause.getClass().getSimpleName())
                     .code(Response.Status.BAD_REQUEST.getStatusCode())
                     .description(Response.Status.BAD_REQUEST.getReasonPhrase())
-                    .message(ErrorUtil.getErrorMessage(service, 
"GenericServiceValidationErrorMessage", request.getLocale()))
+                    .message(RestApiUtil.getErrorMessage(service, 
"GenericServiceValidationErrorMessage", request.getLocale()))
                     .errorDesc((validationException.getMessage()))
                     .additionalErrors(validationException.getMessageList());
             builder = 
Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON).entity(error);
@@ -88,7 +87,7 @@ public class GenericServiceExceptionMapper extends 
AbstractExceptionMapper imple
             Error error = new 
Error().type(actualCause.getClass().getSimpleName())
                     
.code(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
                     
.description(Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase())
-                    .message(ErrorUtil.getErrorMessage(service, 
"NoSuchEntityDefaultMessage", request.getLocale()))
+                    .message(RestApiUtil.getErrorMessage(service, 
"NoSuchEntityDefaultMessage", request.getLocale()))
                     .errorDesc(ExceptionUtils.getRootCauseMessage(gse));
             builder = 
Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON)
                     .entity(error);
@@ -96,7 +95,7 @@ public class GenericServiceExceptionMapper extends 
AbstractExceptionMapper imple
             Error error = new 
Error().type(actualCause.getClass().getSimpleName())
                     
.code(ResponseStatus.Custom.UNPROCESSABLE_ENTITY.getStatusCode())
                     
.description(ResponseStatus.Custom.UNPROCESSABLE_ENTITY.getReasonPhrase())
-                    .message(ErrorUtil.getErrorMessage(service, 
"GenericServiceExecutionGenericEntityOperationErrorMessage",
+                    .message(RestApiUtil.getErrorMessage(service, 
"GenericServiceExecutionGenericEntityOperationErrorMessage",
                             request.getLocale()))
                     .errorDesc(ExceptionUtils.getRootCauseMessage(gse));
             builder = 
Response.status(ResponseStatus.Custom.UNPROCESSABLE_ENTITY).type(MediaType.APPLICATION_JSON)
@@ -105,7 +104,7 @@ public class GenericServiceExceptionMapper extends 
AbstractExceptionMapper imple
             Error error = new 
Error().type(actualCause.getClass().getSimpleName())
                     
.code(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
                     
.description(Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase())
-                    .message(ErrorUtil.getErrorMessage(service, 
"GenericServiceExecutionGenericExceptionErrorMessage",
+                    .message(RestApiUtil.getErrorMessage(service, 
"GenericServiceExecutionGenericExceptionErrorMessage",
                             request.getLocale()))
                     .errorDesc(ExceptionUtils.getRootCauseMessage(gse));
             builder = 
Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON)
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GlobalExceptionMapper.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GlobalExceptionMapper.java
index f2ec0dd7f..c95891432 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GlobalExceptionMapper.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GlobalExceptionMapper.java
@@ -18,15 +18,16 @@
  
*******************************************************************************/
 package org.apache.ofbiz.ws.rs.spi.impl;
 
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.ext.Provider;
 
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.ws.rs.response.Error;
-import org.apache.ofbiz.ws.rs.spi.AbstractExceptionMapper;
 
 @Provider
-public class GlobalExceptionMapper extends AbstractExceptionMapper implements 
jakarta.ws.rs.ext.ExceptionMapper<Throwable> {
+public class GlobalExceptionMapper implements 
jakarta.ws.rs.ext.ExceptionMapper<Throwable> {
 
     /**
      * Module Name Used for debugging
@@ -44,9 +45,12 @@ public class GlobalExceptionMapper extends 
AbstractExceptionMapper implements ja
         if (Debug.verboseOn()) {
             throwable.printStackTrace();
         }
-        Response.StatusType type = getStatusType(throwable);
+        Response.StatusType type = (throwable instanceof 
WebApplicationException
+                    ? ((WebApplicationException) 
throwable).getResponse().getStatusInfo()
+                    : Response.Status.INTERNAL_SERVER_ERROR);
+
         Error error = new Error(type.getStatusCode(), type.getReasonPhrase(), 
throwable.getMessage());
-        return errorResponse(type.getStatusCode(), error);
+        return 
Response.status(type.getStatusCode()).entity(error).type(MediaType.APPLICATION_JSON).build();
     }
 
 }
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/JsonifiedParamConverterProvider.java
 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/JsonifiedParamConverterProvider.java
index 0990002f0..8fc0e8a03 100644
--- 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/JsonifiedParamConverterProvider.java
+++ 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/JsonifiedParamConverterProvider.java
@@ -48,6 +48,7 @@ public class JsonifiedParamConverterProvider implements 
ParamConverterProvider {
 
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
+    // TODO: check thread safety and performance
     private static ObjectMapper getMapper() {
         return MAPPER;
     }
diff --git a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/ErrorUtil.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/ErrorUtil.java
deleted file mode 100644
index 3740944d0..000000000
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/ErrorUtil.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- *
- */
-package org.apache.ofbiz.ws.rs.util;
-
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- 
*******************************************************************************/
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-
-import org.apache.ofbiz.base.util.UtilProperties;
-import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.service.ModelService;
-import org.apache.ofbiz.ws.rs.core.ResponseStatus;
-import org.apache.ofbiz.ws.rs.response.Error;
-
-public final class ErrorUtil {
-
-    private ErrorUtil() {
-
-    }
-
-    private static final String DEFAULT_MSG_UI_LABEL_RESOURCE = "ApiUiLabels";
-
-    @SuppressWarnings("unchecked")
-    public static Response buildErrorFromServiceResult(String service, 
Map<String, Object> result, Locale locale) {
-        String errorMessage = null;
-        List<String> additionalErrorMessages = new LinkedList<>();
-        if (!UtilValidate.isEmpty(result.get(ModelService.ERROR_MESSAGE))) {
-            errorMessage = result.get(ModelService.ERROR_MESSAGE).toString();
-        }
-        if 
(!UtilValidate.isEmpty(result.get(ModelService.ERROR_MESSAGE_LIST))) {
-            List<String> errorMessageList = (List<String>) 
result.get(ModelService.ERROR_MESSAGE_LIST);
-            if (UtilValidate.isEmpty(errorMessage)) {
-                errorMessage = errorMessageList.get(0);
-                errorMessageList.remove(0);
-            }
-            for (int i = 0; i < errorMessageList.size(); i++) {
-                additionalErrorMessages.add(errorMessageList.get(i));
-            }
-        }
-        Error error = new 
Error().type("ServiceError").code(ResponseStatus.Custom.UNPROCESSABLE_ENTITY.getStatusCode())
-                
.description(ResponseStatus.Custom.UNPROCESSABLE_ENTITY.getReasonPhrase())
-                .message(getErrorMessage(service, 
"GenericServiceErrorMessage", locale)).errorDesc(errorMessage);
-        return 
Response.status(ResponseStatus.Custom.UNPROCESSABLE_ENTITY).type(MediaType.APPLICATION_JSON)
-                .entity(error).build();
-    }
-
-    public static String getErrorMessage(String serviceName, String errorKey, 
Locale locale) {
-        String error = 
UtilProperties.getMessage(DEFAULT_MSG_UI_LABEL_RESOURCE, errorKey, locale);
-        error = error.replace("${service}", serviceName);
-        return error;
-    }
-}
diff --git 
a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/RestApiUtil.java 
b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/RestApiUtil.java
index 70109a55a..49c19fc03 100644
--- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/RestApiUtil.java
+++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/util/RestApiUtil.java
@@ -20,7 +20,9 @@ package org.apache.ofbiz.ws.rs.util;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 import jakarta.ws.rs.core.MediaType;
@@ -28,19 +30,24 @@ import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.Response.ResponseBuilder;
 
+import org.apache.ofbiz.base.util.UtilProperties;
 import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.service.ModelService;
+import org.apache.ofbiz.ws.rs.core.ResponseStatus;
 import org.apache.ofbiz.ws.rs.response.Error;
 import org.apache.ofbiz.ws.rs.response.Success;
 
 public final class RestApiUtil {
 
+    private static final String DEFAULT_MSG_UI_LABEL_RESOURCE = "ApiUiLabels";
+
     private RestApiUtil() {
 
     }
 
     public static Response success(String message, Object data) {
         Success success = new Success(Response.Status.OK.getStatusCode(), 
Response.Status.OK.getReasonPhrase(), message, data);
-        return 
Response.status(Response.Status.OK.getStatusCode()).type(MediaType.APPLICATION_JSON).entity(success).build();
+        return 
Response.status(Response.Status.OK).type(MediaType.APPLICATION_JSON).entity(success).build();
     }
 
     public static Response error(int statusCode, String reasonPhrase, String 
message) {
@@ -48,10 +55,6 @@ public final class RestApiUtil {
         return 
Response.status(statusCode).type(MediaType.APPLICATION_JSON).entity(error).build();
     }
 
-    /**
-     * @param message
-     * @return
-     */
     public static ResponseBuilder errorBuilder(int statusCode, String 
reasonPhrase, String message) {
         Error error = new Error(statusCode, reasonPhrase, message);
         return 
Response.status(statusCode).type(MediaType.APPLICATION_JSON).entity(error);
@@ -89,4 +92,34 @@ public final class RestApiUtil {
         }
         return pathParams;
     }
+
+    @SuppressWarnings("unchecked")
+    public static Response buildErrorFromServiceResult(String service, 
Map<String, Object> result, Locale locale) {
+        String errorMessage = null;
+        List<String> additionalErrorMessages = new LinkedList<>();
+        if (!UtilValidate.isEmpty(result.get(ModelService.ERROR_MESSAGE))) {
+            errorMessage = result.get(ModelService.ERROR_MESSAGE).toString();
+        }
+        if 
(!UtilValidate.isEmpty(result.get(ModelService.ERROR_MESSAGE_LIST))) {
+            List<String> errorMessageList = (List<String>) 
result.get(ModelService.ERROR_MESSAGE_LIST);
+            if (UtilValidate.isEmpty(errorMessage)) {
+                errorMessage = errorMessageList.get(0);
+                errorMessageList.remove(0);
+            }
+            for (int i = 0; i < errorMessageList.size(); i++) {
+                additionalErrorMessages.add(errorMessageList.get(i));
+            }
+        }
+        Error error = new 
Error().type("ServiceError").code(ResponseStatus.Custom.UNPROCESSABLE_ENTITY.getStatusCode())
+                
.description(ResponseStatus.Custom.UNPROCESSABLE_ENTITY.getReasonPhrase())
+                .message(getErrorMessage(service, 
"GenericServiceErrorMessage", locale)).errorDesc(errorMessage);
+        return 
Response.status(ResponseStatus.Custom.UNPROCESSABLE_ENTITY).type(MediaType.APPLICATION_JSON)
+                .entity(error).build();
+    }
+
+    public static String getErrorMessage(String serviceName, String errorKey, 
Locale locale) {
+        String error = 
UtilProperties.getMessage(DEFAULT_MSG_UI_LABEL_RESOURCE, errorKey, locale);
+        error = error.replace("${service}", serviceName);
+        return error;
+    }
 }

Reply via email to