Подтвердить что ты не робот

Spring MVC: Как вернуть пользовательские 404 ошибок?

Я ищу чистый способ вернуть настроенные 404 ошибки в Spring 4, если запрошенный ресурс не найден. Запросы к различным типам доменов должны приводить к разным страницам ошибок.

Вот какой код, чтобы показать мое намерение (Meter - класс домена):

@RequestMapping(value = "/{number}", method = RequestMethod.GET)
public String getMeterDetails(@PathVariable("number") final Long number, final Model model) {
    final Meter result = meterService.findOne(number);
    if (result == null) {
        // here some code to return an errorpage
    }

    model.addAttribute("meter", result);
    return "meters/details";
}

Я представляю несколько способов решения проблемы. Сначала появилась возможность создать RuntimeException like

@ResponseStatus(HttpStatus.NOT_FOUND)
public class MeterNotFoundExcption extends RuntimeException { }

а затем используйте обработчик исключений для создания настраиваемой страницы ошибок (возможно, содержащая ссылку на список счетчиков или что-то подходящее).

Но мне не нравится загрязнение моего приложения многими небольшими исключениями.

Другая возможность - использовать HttpServletResponse и установить код состояния вручную:

@RequestMapping(value = "/{number}", method = RequestMethod.GET)
public String getMeterDetails(@PathVariable("number") final Long number, final Model model,
final HttpServletResponse response) {
    final Meter meter = meterService.findOne(number);
    if (meter == null) {
        response.setStatus(HttpStatus.NOT_FOUND.value());
        return "meters/notfound";
    }

    model.addAttribute("meter", meter);
    return "meters/details";
}

Но с этим решением я должен дублировать первые 5 строк для многих методов контроллера (например, редактировать, удалять).

Есть ли элегантный способ предотвратить дублирование этих строк много раз?

4b9b3361

Ответ 1

Решение намного проще, чем мысли. Можно использовать один общий ResourceNotFoundException, определенный следующим образом:

public class ResourceNotFoundException extends RuntimeException { }

тогда можно обрабатывать ошибки внутри каждого контроллера с помощью аннотации ExceptionHandler:

class MeterController {
    // ...
    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleResourceNotFoundException() {
        return "meters/notfound";
    }

    // ...

    @RequestMapping(value = "/{number}/edit", method = RequestMethod.GET)
    public String viewEdit(@PathVariable("number") final Meter meter,
                           final Model model) {
        if (meter == null) throw new ResourceNotFoundException();

        model.addAttribute("meter", meter);
        return "meters/edit";
    }
}

Каждый контроллер может определить свой собственный ExceptionHandler для ResourceNotFoundException.

Ответ 2

изменил ваш файл web.xml. Используя следующий код.

<display-name>App Name </display-name>
<error-page>
<error-code>500</error-code>
<location>/error500.jsp</location>
</error-page>

<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>

Доступ к этому по следующему коду.

response.sendError(508802,"Error Message");

Теперь добавьте этот код в web.xml.

<error-page>
<error-code>508802</error-code>
<location>/error500.jsp</location>
</error-page>

Ответ 3

Вы можете отобразить коды ошибок в web.xml следующим образом

    <error-page>
        <error-code>400</error-code>
        <location>/400</location>
    </error-page>

    <error-page>
        <error-code>404</error-code>
        <location>/404</location>
    </error-page>

    <error-page>
        <error-code>500</error-code>
        <location>/500</location>
    </error-page>

Теперь вы можете создать контроллер, чтобы отобразить URL-адрес, который попадет при обнаружении любой из этих ошибок.

@Controller
public class HTTPErrorHandler{

    String path = "/error";

    @RequestMapping(value="/404")
    public String error404(){
       // DO stuff here 
        return path+"/404";
    }
    }

Для полного примера см. Мой учебник об этом

Ответ 4

Вы должны следовать этой статье, где вы можете найти подробную информацию об обработке исключений в проектах Spring MVC.

spring-mvc-exception-handling

@ControllerAdvice может помочь вам в этом случае

Ответ 5

Мы можем просто добавить следующие строки кода в файл web.xml и ввести новый файл jsp с именем errorPage.jsp в корневую директорию проекта, чтобы выполнить это требование.

<error-page>
    <error-code>400</error-code>
    <location>/errorPage.jsp</location>
</error-page>
<error-page>
    <error-code>404</error-code>
    <location>/errorPage.jsp</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/errorPage.jsp</location>
</error-page>

Ответ 6

Простой ответ на 100% бесплатный XML:

  1. Установить свойства для DispatcherServlet

    public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfig.class  };
    }
    
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {AppConfig.class  };
    }
    
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
    
    //that important!!
    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true
        if(!done) throw new RuntimeException();
    }
    

    }

  2. Создать @ControllerAdvice:

    @ControllerAdvice
    public class AdviceController {
    
    @ExceptionHandler(NoHandlerFoundException.class)
    public String handle(Exception ex) {
        return "redirect:/404";
    }
    
    @RequestMapping(value = {"/404"}, method = RequestMethod.GET)
    public String NotFoudPage() {
        return "404";
    
    }
    

    }

  3. Создать страницу 404.jsp с любым контентом

Все это.

Ответ 7

Мне также нужно было НЕ использовать org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.

Согласно org.springframework.web.servlet.DispatcherServlet.setThrowExceptionIfNoHandlerFound(boolean): "Обратите внимание, что если используется DefaultServletHttpRequestHandler, то запросы всегда будут перенаправляться сервлету по умолчанию, а исключение NoHandlerFoundException никогда не будет выброшено".

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html#setThrowExceptionIfNoHandlerFound-boolean-

До

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.foo.web")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

  @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
  }

  // ...
}

После

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.foo.web")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

  @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
  }

  // ...
}

Ответ 8

Я работаю с проектом Netbeans. Я добавил следующие строки в свой web.xml. Он работает только тогда, когда я даю путь из папки WEB-INF следующим образом.

    <error-page>
        <error-code>404</error-code>
        <location>/WEB-INF/view/common/errorPage.jsp</location>
    </error-page>