Как выловить java util nosuchelementexception
Перейти к содержимому

Как выловить java util nosuchelementexception

  • автор:

No Such Element Exception Класс

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

[Android.Runtime.Register("java/util/NoSuchElementException", DoNotGenerateAcw=true)] public class NoSuchElementException : Java.Lang.RuntimeException
[] type NoSuchElementException = class inherit RuntimeException

Наследование
NoSuchElementException
Производный

Комментарии

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Добавлено в версии 1.0.

Части этой страницы являются изменениями, основанными на работе, созданной и совместно используемой проектом Android и используемой в соответствии с условиями, Creative Commons 2.5 Attribution License.

Конструкторы

NoSuchElementException Создает с null в качестве строки сообщения об ошибке.

Конструктор, используемый при создании управляемых представлений объектов JNI; вызывается средой выполнения.

NoSuchElementException Создает , сохраняя ссылку на строку s сообщения об ошибке для последующего извлечения методом getMessage .

Создает с NoSuchElementException указанным подробным сообщением и причиной.

Создает с указанной NoSuchElementException причиной.

Поля

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Свойства

Возвращает причину этого вызываемого объекта или null значение , если причина не существует или неизвестна.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Дескриптор базового экземпляра Android.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создает локализованное описание этого вызываемого объекта.

Возвращает строку подробного сообщения этого вызываемого объекта.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Этот API поддерживает инфраструктуру Mono для Android и не предназначен для использования непосредственно из кода.

Этот API поддерживает инфраструктуру Mono для Android и не предназначен для использования непосредственно из кода.

Методы

Добавляет указанное исключение к исключениям, которые были подавлены для доставки этого исключения.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Заполняет трассировку стека выполнения.

Предоставляет программный доступ к сведениям трассировки стека, напечатанным . #printStackTrace()

Возвращает массив, содержащий все исключения, которые были подавлены, как правило, инструкцией try -with-resources, для доставки этого исключения.

Инициализирует причину этого вызываемого объекта указанным значением.

Выводит этот вызываемый объект и его обратную передачу в стандартный поток ошибок.

Выводит этот бросаемый объект и его обратную передачу в указанный поток печати.

Выводит этот бросаемый объект и его обратную сторону в указанный модуль записи печати.

Задает элементы трассировки стека, которые будут возвращены #getStackTrace() и напечатаны связанными методами #printStackTrace() и .

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Явные реализации интерфейса

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Методы расширения

Выполняет преобразование типа, проверенного средой выполнения Android.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Создается различными методами доступа, чтобы указать, что запрашиваемый элемент не существует.

Выбрасывается исключение java.util.NoSuchElementException при закрытии Scanner

При добавлении студентов dataBase.AddStudents(); в методе класса DataBase открывается сканер Scanner scan = new Scanner(System.in) , после чего, он закрывается: scan.close(); . И когда вызывается повторно метод AddStudents(): dataBase.AddStudents(); выбрасывается исключение java.util.NoSuchElementException . Причем, если убрать строчку scan.close(); в классе DataBase, исключение не выбрасывается. Как это связано с закрытием Scanner, и как исправить эту ошибку?

Отслеживать
задан 2 авг 2021 в 23:28
teoretik_eugene teoretik_eugene
59 4 4 бронзовых знака

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Проблема в том, что метод Scanner.close закрывает тот InputStream , который ему передали.

Это значит, что после первого вызова AddStudents вы закрываете System.in , а значит последующие попытки чтения из него приведут к ошибке, что, собственно, и просходит.

В этом случае правильно (и проще всего тоже) не закрывать scanner, так как у вас всегда передается System.in , а этот поток вообще закрывать не имеет смысла.

В некоторых случаях у вас может быть универсальный код со Scanner , то есть такой, который не знает какой именно ему InputStream передается, но он принимает его во владение. Под владением я имею ввиду то, что этот код является ответственным за закрытие переданного InputStream . И так как он не знает, передан ему поток ввода созданный из файла (который можно и должно закрывать) или System.in , то тут возникает проблема.

Ее решают тем, что передают не непосредственно System.in , а заворачивают его в декоратор для InputStream , который игнорирует вызов метода close . В JDK такого нету (по крайней мере до версии 8 точно не было, может сейчас изменилось что-то), но есть в apache commons.

Spring Boot REST API – обработка исключений. Часть 1

Мы рассмотрим простое REST API приложение с одной сущностью Person и с одним контроллером.

@Entity @NoArgsConstructor @AllArgsConstructor @Data public class Person

@RestController @RequestMapping("/persons") public class PersonController < @Autowired private PersonRepository personRepository; @GetMapping public ListlistAllPersons() < Listpersons = personRepository.findAll(); return persons; > @GetMapping(value = "/") public Person getPerson(@PathVariable("personId") long personId) < return personRepository.findById(personId).orElseThrow(() ->new MyEntityNotFoundException(personId)); > @PostMapping public Person createPerson(@RequestBody Person person) < return personRepository.save(person); >@PutMapping("/") public Person updatePerson(@RequestBody Person person, @PathVariable long id) < Person oldPerson = personRepository.getOne(id); oldPerson.setName(person.getName()); return personRepository.save(oldPerson); >>

При старте приложения выполняется скрипт data.sql, который добавляет в базу данных H2 одну строку — Person c То есть Person c в базе отсутствует.

При попытке запросить Person c id=2:

GET localhost:8080/persons/2

метод контроллера getPerson() выбрасывает исключение — в данном случае наше пользовательское MyEntityNotFoundException:

public class MyEntityNotFoundException extends RuntimeException < public MyEntityNotFoundException(Long id) < super("Entity is not found, id EnlighterJSRAW" data-enlighter-language="java">@Controller @RequestMapping(>">) public class BasicErrorController extends AbstractErrorController < . @RequestMapping public ResponseEntity> error(HttpServletRequest request) < HttpStatus status = this.getStatus(request); if (status == HttpStatus.NO_CONTENT) < return new ResponseEntity(status); >else < Mapbody = this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.ALL)); return new ResponseEntity(body, status); > > . >

Если поставить в этом методе break point, то будет понятно, из каких атрибутов собирается ответное JSON сообщение.

Проверим ответ по умолчанию, запросив с помощью клиента Postman отсутствующий Person, чтобы выбросилось MyEntityNotFoundException:

GET localhost:8080/persons/2

Причем для того, чтобы поле message было непустым, в application.properties нужно включить свойство:

server.error.include-message=always

В текущей версии Spring сообщение не включается по умолчанию из соображений безопасности.

Обратите внимание, что поле status JSON-тела ответа дублирует реальный http-код ответа. В Postman он виден:

Поле message заполняется полем message выброшенного исключения.

Независимо от того, какое исключение выбросилось: пользовательское или уже существующее, ответ стандартный — в том смысле, что набор полей одинаковый. Меняется только внутренняя часть и, возможно, код ответа (он не обязательно равен 500, некоторые существующие в Spring исключения подразумевают другой код).

Но структура ответа сохраняется.

Не пользовательское исключение

Например, если изменить код, убрав пользовательское MyEntityNotFoundException, то при отсутствии Person исключение будет все равно выбрасываться, но другое:

@GetMapping(value = «/») public Person getPerson(@PathVariable(«personId») long personId)

findById() возвращает тип Optional, а Optional.get() выбрасывает исключение NoSuchElementException с другим сообщением:

java.util.NoSuchElementException: No value present

в итоге при запросе несуществующего Person:

GET localhost:8080/persons/2

ответ сохранит ту же структуру, но поменяется поле message:

Вернем обратно пользовательское исключение MyEntityNotFoundException.

Попробуем поменять ответ, выдаваемый в ответ за запрос. Статус 500 для него явно не подходит.

Рассмотрим способы изменения ответа.

@ResponseStatus

Пока поменяем только статус ответа. Сейчас возвращается 500, а нам нужен 404 — это логичный ответ, если ресурс не найден.

Для этого аннотируем наше исключение:

@ResponseStatus(HttpStatus.NOT_FOUND) public class MyEntityNotFoundException extends RuntimeException < public MyEntityNotFoundException(Long id) < super("Entity is not found, id EnlighterJSRAW" data-enlighter-language="java">< "timestamp": "2021-02-28T15:54:37.070+00:00", "status": 404, "error": "Not Found", "message": "Entity is not found, "path": "/persons/2" >

@ControllerAdvice

Есть еще более мощный способ изменить ответ — @ControllerAdvice, и он имеет больший приоритет, чем @ResponseStatus.

В @ControllerAdvice можно не только изменить код ответа, но и тело. К тому же один обработчик можно назначить сразу для нескольких исключений.

Допустим мы хотим, чтобы ответ на запрос несуществующего Person имел такую структуру:

@Data @AllArgsConstructor @NoArgsConstructor public class ApiError

Для этого создадим обработчик в @ControllerAdvice, который перехватывает наше исключение MyEntityNotFoundException:

@ControllerAdvice public class RestExceptionHandler < @ExceptionHandler() protected ResponseEntity handleEntityNotFoundEx(RuntimeException ex, WebRequest request) < ApiError apiError = new ApiError("entity not found ex", ex.getMessage()); return new ResponseEntity<>(apiError, HttpStatus.NOT_FOUND); > >

Теперь в ответ на запрос

GET localhost:8080/persons/2

мы получаем статус 404 с телом:

< "message": "entity not found ex", "debugMessage": "Entity is not found, >Но помимо MyEntityNotFoundException, наш обработчик поддерживает и javax.persistence.EntityNotFoundException (см. код выше).

Попробуем сделать так, чтобы оно возникло.

Это исключение EntityNotFoundException возникает в методе updatePerson() в контроллера. А именно, когда мы обращаемся с помощью метода PUT к несуществующей сущности в попытке назначить ей имя:

PUT localhost:8080/persons/2

В этом случае мы тоже получим ответ с новой структурой:

Итого, обработчик в @ControllerAdvice позволил изменить не только код ответа, но и тело сообщение. Причем один обработчик мы применили для двух исключений.

Последовательность проверок

Обратите внимание, что MyEntityNotFoundException мы «обработали» дважды — изменили код с помощью @ResponseStatus (1) и прописали в @ContollerAdvice — тут изменили как код, так и тело ответа (2). Эти обработки могли быть противоречивы, но существует приоритет:

  • Когда выбрасывается исключение MyEntityNotFoundException, сначала Spring проверяет @ControllerAdvice-класс. А именно, нет ли в нем обработчика, поддерживающего наше исключение. Если обработчик есть, то исключение в нем и обрабатывается. В этом случае код @ResponseStatus значения не имеет, и в BasicErrorController исключение тоже не идет.
  • Если исключение не поддерживается в @ControllerAdvice-классе, то оно идет в BasicErrorController. Но перед этим Spring проверяет, не аннотировано ли исключение аннотацией @ResponseStatus. Если да, то код ответа меняется, как указано в @ResponseStatus. Далее формируется ответ в BasicErrorController.
  • Если же первые два условия не выполняются, то исключение обрабатывается сразу в BasicErrorController — там формируется стандартный ответ со стандартным кодом (для пользовательских исключений он равен 500).

Но и стандартный ответ можно изменить, для этого нужно расширить класс DefaultErrorAttributes.

Попробуем это сделать.

Изменение DefaultErrorAttributes

Давайте добавим в стандартный ответ еще одно поле. Для этого расширим класс:

@Component public class CustomErrorAttributes extends DefaultErrorAttributes < @Override public MapgetErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) < MaperrorAttributes=super.getErrorAttributes(webRequest, options); errorAttributes.put("newAttribute", "value"); return errorAttributes; > >

В Map errorAttributes перечисляются поля ответа. Мы взяли их из родительского метода и добавили свое поле newAttribute.

Чтобы выполнить проверку, надо убрать @ControllerAdvice, поскольку он самый приоритетный и с ним мы даже не дойдем до BasicErrorController со «стандартными» полями.

Далее запросим ресурс:

localhost:8080/persons/2

В JSON-ответе появилось дополнительное поле.

ResponseStatusException

Рассмотрим еще один вариант, позволяющий сразу протолкнуть код ответа и сообщение стандартные поля, не прописывая обработку пользовательских или встроенных исключений. А вместо этого просто выбросив специально предназначенное исключение ResponseStatusException.

Изменим код метода контроллера getPerson():

@GetMapping(value = "/") public Person getPerson(@PathVariable("personId") long personId) < return personRepository.findById(personId).orElseThrow(() ->new ResponseStatusException( HttpStatus.NOT_FOUND, "Person Not Found")); >

Теперь тут не выбрасывается ни MyEntityNotFoundException, ни java.util.NoSuchElementException. А выбрасывается ResponseStatusException с заданным сообщением и кодом ответа.

Теперь при запросе

GET localhost:8080/persons/2

ответ будет таким:

Как код, так и сообщение появилось в полях стандартного ответа.

ResponseStatusException не вступает в конкуренцию ни со способом @ControllerAdvice, ни с @ResponseStatus — просто потому, что это другое исключение.

Итоги

Код примера доступен на GitHub. В следующей части мы унаследуем RestExceptionHandler от ResponseEntityExceptionHandler. Это класс-заготовка, которая уже обрабатывает ряд исключений.

Как выловить java util nosuchelementexception

Constructs a NoSuchElementException , saving a reference to the error message string s for later retrieval by the getMessage method.

Method Summary

Methods inherited from class java.lang.Throwable

Methods inherited from class java.lang.Object

Constructor Detail

NoSuchElementException
public NoSuchElementException()

Constructs a NoSuchElementException with null as its error message string.

NoSuchElementException

Constructs a NoSuchElementException , saving a reference to the error message string s for later retrieval by the getMessage method.

Java™ Platform
Standard Ed. 8

Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2024, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *