Source:
public void handlePost(ActionParameters params) throws ActionException { params.requireLoggedInUser(); try { JSONArray paramFeatures = new JSONArray(params.getHttpParam("featureData")); for (int i = 0; i < paramFeatures.length(); i++) { JSONObject featureJSON = paramFeatures.getJSONObject(i); OskariLayer layer = getLayer(featureJSON.optString("layerId")); if (!canEdit(layer, params.getUser())) { throw new ActionDeniedException("User doesn't have edit permission for layer: " + layer.getId()); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); List<Feature> features = new ArrayList<>(); Feature feature = getFeature(featureJSON); features.add(feature); FeatureWFSTRequestBuilder.updateFeatures(baos, features); final String wfstMessage = baos.toString(); LOG.debug("Updating feature to service at", layer.getUrl(), "with payload", wfstMessage); String responseString = postPayload(layer, wfstMessage); flushLayerTilesCache(layer.getId()); if (responseString.indexOf("Exception") > -1) { throw new ActionException("Cannot save feature: " + responseString); } else if (responseString.indexOf("<wfs:totalUpdated>1</wfs:totalUpdated>") > -1) { ResponseHelper.writeResponse(params, "Feature updated"); } } } catch (JSONException e) { LOG.error(e, "JSON processing error"); throw new ActionException("JSON processing error", e); } catch (XMLStreamException e) { LOG.error(e, "Failed to create WFS-T request"); throw new ActionException("Failed to create WFS-T request", e); } catch (FactoryException e) { LOG.error(e, "Failed to create WFS-T request (crs)"); throw new ActionException("Failed to create WFS-T request (crs)", e); } }

Target:
public void handlePost(ActionParameters params) throws ActionException { params.requireLoggedInUser(); List<String> exceptions = new ArrayList<>(); try { JSONArray paramFeatures = new JSONArray(params.getHttpParam("featureData")); Map<Integer, OskariLayer> layers = getLayers(paramFeatures); hasUserPermissionEditLayers(layers, params.getUser()); for (int i = 0; i < paramFeatures.length(); i++) { JSONObject featureJSON = paramFeatures.getJSONObject(i); OskariLayer layer = getLayer(featureJSON.optString("layerId")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Feature feature = getFeature(featureJSON); FeatureWFSTRequestBuilder.updateFeature(baos, feature); final String wfstMessage = baos.toString(); LOG.debug("Updating feature to service at", layer.getUrl(), "with payload", wfstMessage); String responseString = postPayload(layer, wfstMessage); if (responseString.indexOf("Exception") > -1) { exceptions.add(responseString); } } flushLayerTilesCache(layers); if(exceptions.size() == paramFeatures.length()) { throw new ActionException("Cannot save features: " + exceptions.toString()); } JSONObject response = new JSONObject(); response.put("success", true); if( exceptions.size() == 0) { ResponseHelper.writeResponse(params, response); } else { response.put("messageKey", "cannot_save_all_features"); ResponseHelper.writeResponse(params, response); } } catch (JSONException e) { LOG.error(e, "JSON processing error"); throw new ActionException("JSON processing error", e); } catch (XMLStreamException e) { LOG.error(e, "Failed to create WFS-T request"); throw new ActionException("Failed to create WFS-T request", e); } catch (FactoryException e) { LOG.error(e, "Failed to create WFS-T request (crs)"); throw new ActionException("Failed to create WFS-T request (crs)", e); } }