【问题标题】:Spring MVC - Displaying Exception in View (JSP Page)Spring MVC - 在视图中显示异常(JSP 页面)
【发布时间】:2017-01-03 10:11:31
【问题描述】:

我在 Spring MVC 中创建了一个应用程序,用于测试回滚和提交功能。我正在使用事务。在服务中,我创建了另一个联系人对象,但未指定必填字段的员工 ID。当保存和回滚工作时出现异常时,应用程序可以正常工作。

但问题是异常正在我的 jsp 页面中打印。

谁能告诉我一些防止在视图中显示异常的解决方案

控制器

@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contacts contact, BindingResult result, SessionStatus status)
{
    validator.validate(contact, result);
    if (result.hasErrors()) 
    {               
        return "newContact";
    }
    contactsDAO.save(contact);
    status.setComplete();
    return "redirect:viewAllContacts.do";
}

服务

public int save(Contacts contact)
{
    int i = 0;
    try
    {
        i = (Integer) sessionFactory.getCurrentSession().save(contact);
        Contacts contacts =new Contacts();
        contacts.setAddress("ABCD");
        contacts.setMobile("8181");
        i = (Integer) sessionFactory.getCurrentSession().save(contacts);
    }
    catch(Exception exception)
    {
        exception.printStackTrace();
    }
    return i;
}

编辑

@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contacts contact, BindingResult result, SessionStatus status) throws SQLException
{
    validator.validate(contact, result);
    if (result.hasErrors()) 
    {               
        return "newContact";
    }
    try {
        contactsDAO.save(contact); 
    }
    catch (Exception ex) {
        System.out.println("enrtered");
        result.reject("DUPKEY");
        ex.printStackTrace();
        return "redirect:saveContact.do";
    } 
    status.setComplete();
    return "redirect:viewAllContacts.do";
}

【问题讨论】:

  • 检查/配置spring异常解析器
  • @user3145373ツ 实际上正如我所说,我已经创建了一个异常来检查回滚功能
  • 您能否解释一下异常是什么,如果它是您在服务中捕获的异常(以及它是如何重新抛出的)以及什么意思:在我的 jsp 中打印 ?它是出现在预期页面的中间还是出现在预期页面的中间?
  • @SergeBallesta 看到这里异常不是问题,因为我使用的是@Transactional,所以我们在事务期间遇到了一些异常@ 没有必要明确定义事务。因此,当发生异常时,它会抛出并向用户显示该异常,而不是我如何告诉用户某些事情出错了
  • @SergeBallesta 和Hibernate, Spring, @Transactional - surround with try/catch? 一样,但是我没有得到任何解决方案,您能否指定一些与上述代码相关的代码

标签: java spring jsp spring-mvc


【解决方案1】:

你应该永远不要让服务层抛出的异常直接到达用户浏览器。正如 Vinit Prajapati 所建议的,您可以配置一个HandlerExceptionResolver,以在出现异常时显示适当的视图。您还可以拥有一个每个控制器的异常处理机制,其中包含一个或多个 @ExceptionHandler 注释方法,这些方法将在配置异常的情况下被触发,并且几乎可以像 @RequestMapping 注释方法一样使用。最后,您可以在控制器方法中使用显式的 try-catch 块。

摘自 Spring Framework 参考手册:您在控制器中使用 @ExceptionHandler 方法注释来指定在控制器方法执行期间抛出特定类型的异常时调用哪个方法... @ExceptionHandler value 可以设置为异常类型的数组。如果抛出的异常与列表中的一种类型匹配,则将调用使用匹配的 @ExceptionHandler 注释的方法......与使用 @RequestMapping 注释注释的标准控制器方法非常相似,@ExceptionHandler 的方法参数和返回值方法非常灵活...返回类型可以是String,可以解释为视图名或ModelAndView对象。

在我自己的代码中,我使用@ExceptionHandler 处理一般错误,例如无法访问的数据库,但如果我想处理真正由业务规则引起的异常并且我更喜欢使用<form:errors>,则在控制器中使用try-catch blocs视图中的标签,在控制器中显式调用Errors.reject()

编辑:具体示例

假设你想在DataIntegrityViolationException的情况下显示特殊视图

在控制器中

@ExceptionHandler(value = {DataIntegrityViolationException.class})
public ModelAndViewexceptionHandler(Exception ex, Locale locale) {
    String msg = ex.getMessage();
    // or if you have a I18n app : String msg = messageSource.getMessage("DUPKEY", null, locale);
    return new ModelAndView("duplicate", "msg", msg);
}

使用"duplicate" 引导到一个jsp,其中${msg} 将显示异常消息。当然,要使其正常工作,您的服务必须抛出 DataIntegrityViolationException ...

如果您希望错误显示在普通视图中,您可以这样做

@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contacts contact, BindingResult result, SessionStatus status)
{
    validator.validate(contact, result);
    if (result.hasErrors()) 
    {               
        return "newContact";
    }
    try {
        contactsDAO.save(contact);
    }
    catch (DataIntegrityViolationException ex) {
        result.reject("DUPKEY");
        return "newContact";
    }
    status.setComplete();
    return "redirect:viewAllContacts.do";
}

使用最后一个构造,您将在配置的 MessageSourcebean 中显示与 DUPKEY 对应的错误消息,就像您的 jsp 视图中通过标记 <form:errors/> 中没有 path 的其他全局错误一样。

<form:form>
      <%-- Show global errors (notably DUPKEY) --%>
      <form:errors/>
      <table>
          <tr>
              <td>Address:</td>
              <td><form:input path="address" /></td>
              <%-- Show errors for address field --%>
              <td><form:errors path="address" /></td>
          </tr>
...
</form:form>

【讨论】:

  • 你能给我看一个与我的应用相关的例子吗
  • 你能告诉我@ExceptionHandler和它的块有什么用吗,因为我觉得即使你在contactsDAO.save(contact);中放了一个try catch,所以每当发生异常时它如果我们返回到带有相应错误消息的 newContact 或 viewAllContacts 视图,将被捕获并在该捕获块内
  • 刚刚在第二个示例的介绍中添加了而不是。这些示例是排他性的:要么使用 @ExceptionHandler 和专用于异常显示的视图,要么使用 catch 块并在同一视图中继续显示错误。
  • 这意味着当某些异常发生时,如果我们想将其显示到专用的公共异常视图中,我们可以使用@ExceptionHandler,否则如果我们想在同一视图中显示,我们可以通过 catch 本身返回。
  • 谢谢!!,还有一件事,即如果我们想将错误消息从 catch 块传递到我们渲染的同一个视图,我们如何通过 BindingResult 或任何其他方式来做到这一点
【解决方案2】:

创建一个基本控制器类(你的其他人扩展),例如尝试这个方法(虽然你会想用不同的方法处理不同的错误,但这会让你开始):

    /*
 * Default exception handler, catches all exceptions, redirects to friendly
 * error page and send e-mail does not catch request mapping errors
 */
@ExceptionHandler (Exception.class)
public String myExceptionHandler(final Exception e) {
    final StringWriter sw = new StringWriter();
    final PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    final String strStackTrace = sw.toString(); // stack trace as a string
    logger.error(strStackTrace); // send to logger first
    emailService.sendAlertMail(strStackTrace);
    return "exception"; // default friendly exception message for user
}

【讨论】:

  • 但是从我的服务中我将如何通过这个来控制异常
  • 你能给我看一个与我的应用相关的例子吗
猜你喜欢
  • 2011-01-28
  • 2020-06-27
  • 2011-10-21
  • 2019-05-05
  • 1970-01-01
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多