日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 错误输入异常_在Java中进行输入验证期间用错误通知替换异常

發(fā)布時(shí)間:2023/12/3 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 错误输入异常_在Java中进行输入验证期间用错误通知替换异常 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java 錯(cuò)誤輸入異常

在我以前的文章中,我寫了一篇關(guān)于輸入驗(yàn)證設(shè)計(jì)的文章 ,該設(shè)計(jì)取代了難以維護(hù)和測試的 if-else塊。 但是,正如某些讀者指出的那樣,它有一個(gè)缺點(diǎn)–如果輸入數(shù)據(jù)有多個(gè)驗(yàn)證錯(cuò)誤,則用戶將不得不多次提交請求才能找到所有請求。 從可用性的角度來看,這不是一個(gè)好的設(shè)計(jì)。

當(dāng)我們發(fā)現(xiàn)驗(yàn)證錯(cuò)誤時(shí),拋出異常的另一種方法是返回一個(gè)包含錯(cuò)誤的Notification對象。 這將使我們能夠在用戶輸入上運(yùn)行所有驗(yàn)證規(guī)則,并同時(shí)捕獲所有違規(guī)行為。 Martin Fowler 撰寫了一篇文章,詳細(xì)介紹了該方法。 我強(qiáng)烈建議您繼續(xù)閱讀,如果您還沒有讀過的話。

在本文中,我將重構(gòu)以前的實(shí)現(xiàn),以使用錯(cuò)誤通知對象來驗(yàn)證用戶輸入。

第一步,我將創(chuàng)建一個(gè)ErrorNotification對象,該對象封裝了我的應(yīng)用程序錯(cuò)誤-

public class ErrorNotification {private List<String> errors = new ArrayList<>();public void addError(String message) {this.errors.add(message);}public boolean hasError() {return !this.errors.isEmpty();}public String getAllErrors() {return this.errors.stream().collect(joining(", "));} }

然后,我將更改OrderItemValidator接口以返回ErrorNotification對象–

public interface OrderItemValidator {ErrorNotification validate(OrderItem orderItem); }

然后更改所有實(shí)現(xiàn)以適應(yīng)新的返回類型。

最初,我將更改所有實(shí)現(xiàn),以返回一個(gè)空的錯(cuò)誤對象,以便擺脫編譯錯(cuò)誤。 例如,我將通過以下方式更改ItemDescriptionValidator –

class ItemDescriptionValidator implements OrderItemValidator {@Overridepublic ErrorNotification validate(OrderItem orderItem) {ErrorNotification errorNotification = new ErrorNotification();Optional.ofNullable(orderItem).map(OrderItem::getDescription).map(String::trim).filter(description -> !description.isEmpty()).orElseThrow(() -> new IllegalArgumentException("Item description should be provided"));return errorNotification;} }

修復(fù)編譯錯(cuò)誤之后,我現(xiàn)在將開始使用每個(gè)驗(yàn)證器中的通知消息替換異常。 為此,我將首先修改相關(guān)測試以反映我的意圖,然后修改驗(yàn)證器以通過測試。

讓我們從ItemDescriptionValidatorTest類開始–

public class ItemDescriptionValidatorTest {@Testpublic void validate_descriptionIsNull_invalid() {ItemDescriptionValidator validator = new ItemDescriptionValidator();ErrorNotification errorNotification = validator.validate(new OrderItem());assertThat(errorNotification.getAllErrors()).isEqualTo("Item description should be provided");}@Testpublic void validate_descriptionIsBlank_invalid() {OrderItem orderItem = new OrderItem();orderItem.setDescription(" ");ItemDescriptionValidator validator = new ItemDescriptionValidator();ErrorNotification errorNotification = validator.validate(new OrderItem());assertThat(errorNotification.getAllErrors()).isEqualTo("Item description should be provided");}@Testpublic void validate_descriptionGiven_valid() {OrderItem orderItem = new OrderItem();orderItem.setDescription("dummy description");ItemDescriptionValidator validator = new ItemDescriptionValidator();ErrorNotification errorNotification = validator.validate(orderItem);assertThat(errorNotification.getAllErrors()).isEmpty();} }

當(dāng)我運(yùn)行這些測試時(shí),只有其中一項(xiàng)通過,而其中兩項(xiàng)失敗,這是預(yù)料之中的。 我現(xiàn)在將修改驗(yàn)證器代碼以通過測試–

class ItemDescriptionValidator implements OrderItemValidator {static final String MISSING_ITEM_DESCRIPTION = "Item description should be provided";@Overridepublic ErrorNotification validate(OrderItem orderItem) {ErrorNotification errorNotification = new ErrorNotification();Optional.ofNullable(orderItem).map(OrderItem::getDescription).map(String::trim).filter(description -> !description.isEmpty()).ifPresentOrElse(description -> {},() -> errorNotification.addError(MISSING_ITEM_DESCRIPTION));return errorNotification;} }

我對上面的ifPresentOrElse方法的使用感到不舒服。 我在這里使用它的主要原因是因?yàn)镺ptionals沒有ifNotPresent方法之類的東西,它將使我僅在不存在該值的情況下才采取措施(請向讀者提出要求-如果您知道一種更好的方法,為此,請發(fā)表評論!)。

進(jìn)行此重構(gòu)后, ItemValidatorTest類中的所有測試均通過測試。 大!

現(xiàn)在讓我們重構(gòu)MenuValidatorTest類中的測試–

public class MenuValidatorTest {@Testpublic void validate_menuIdInvalid_invalid() {OrderItem orderItem = new OrderItem();String menuId = "some menu id";orderItem.setMenuId(menuId);MenuRepository menuRepository = mock(MenuRepository.class);when(menuRepository.menuExists(any())).thenReturn(false);MenuValidator validator = new MenuValidator(menuRepository);ErrorNotification errorNotification = validator.validate(orderItem);assertThat(errorNotification.getAllErrors()).isEqualTo(String.format(MenuValidator.INVALID_MENU_ERROR_FORMAT, menuId));}@Testpublic void validate_menuIdNull_invalid() {MenuRepository menuRepository = mock(MenuRepository.class);when(menuRepository.menuExists(any())).thenReturn(true);MenuValidator validator = new MenuValidator(menuRepository);ErrorNotification errorNotification = validator.validate(new OrderItem());assertThat(errorNotification.getAllErrors()).isEqualTo(MenuValidator.MISSING_MENU_ERROR);}@Testpublic void validate_menuIdIsBlank_invalid() {OrderItem orderItem = new OrderItem();orderItem.setMenuId(" \t");MenuRepository menuRepository = mock(MenuRepository.class);when(menuRepository.menuExists(any())).thenReturn(true);MenuValidator validator = new MenuValidator(menuRepository);ErrorNotification errorNotification = validator.validate(orderItem);assertThat(errorNotification.getAllErrors()).isEqualTo(MenuValidator.MISSING_MENU_ERROR);}@Testpublic void validate_menuIdValid_validated() {OrderItem orderItem = new OrderItem();String menuId = "some menu id";orderItem.setMenuId(menuId);MenuRepository menuRepository = mock(MenuRepository.class);when(menuRepository.menuExists(menuId)).thenReturn(true);MenuValidator validator = new MenuValidator(menuRepository);ErrorNotification errorNotification = validator.validate(orderItem);assertThat(errorNotification.getAllErrors()).isEmpty();} }

然后是MenuValidator類–

@RequiredArgsConstructor class MenuValidator implements OrderItemValidator {private final MenuRepository menuRepository;static final String MISSING_MENU_ERROR = "A menu item must be specified.";static final String INVALID_MENU_ERROR_FORMAT = "Given menu [%s] does not exist.";@Overridepublic ErrorNotification validate(OrderItem orderItem) {ErrorNotification errorNotification = new ErrorNotification();Optional.ofNullable(orderItem.getMenuId()).map(String::trim).filter(menuId -> !menuId.isEmpty()).ifPresentOrElse(validateMenuExists(errorNotification),() -> errorNotification.addError(MISSING_MENU_ERROR));return errorNotification;}private Consumer<String> validateMenuExists(ErrorNotification errorNotification) {return menuId -> {if (!menuRepository.menuExists(menuId)) {errorNotification.addError(String.format(INVALID_MENU_ERROR_FORMAT, menuId));}};} }

等等。

修改了各個(gè)驗(yàn)證器后,我現(xiàn)在將修改Composite以收集單個(gè)訂單商品的所有錯(cuò)誤–

@RequiredArgsConstructor class OrderItemValidatorComposite implements OrderItemValidator {private final List<OrderItemValidator> validators;@Overridepublic ErrorNotification validate(OrderItem orderItem) {ErrorNotification errorNotification = new ErrorNotification();validators.stream().map(validator -> validator.validate(orderItem)).forEach(errorNotification::addAll);return errorNotification;} }

為此,我在ErrorNotification類中添加了一個(gè)名為addAll的新方法,該方法基本上從另一個(gè)ErrorNotification對象復(fù)制所有錯(cuò)誤。

最后,我現(xiàn)在將修改服務(wù)方法,以收集訂單中所有訂單項(xiàng)的所有錯(cuò)誤消息–

@Service @Slf4j @RequiredArgsConstructor class OrderService {private final OrderItemValidator validator;void createOrder(OrderDTO orderDTO) {ErrorNotification errorNotification = new ErrorNotification();orderDTO.getOrderItems().stream().map(validator::validate).forEach(errorNotification::addAll);if (errorNotification.hasError()) {throw new IllegalArgumentException(errorNotification.getAllErrors());}log.info("Order {} saved", orderDTO);} }

進(jìn)行此更改會導(dǎo)致OrderServiceIT中的測試之一失敗,因?yàn)樗貏e是在價(jià)格無效時(shí)尋找原因設(shè)置為NumberFormatException的異常。 重構(gòu)之后,我們可以安全地刪除此檢查,因?yàn)樗辉傧嚓P(guān)。

本文的完整源代碼已推送到GitHub (特定的提交URL在此處 )。

翻譯自: https://www.javacodegeeks.com/2017/11/replacing-exceptions-error-notifications-input-validation-java.html

java 錯(cuò)誤輸入異常

總結(jié)

以上是生活随笔為你收集整理的java 错误输入异常_在Java中进行输入验证期间用错误通知替换异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。