对于想了解在SpringMVC中渲染视图时如何处理抛出的异常?的读者,本文将提供新的信息,我们将详细介绍springmvc视图,并且为您提供关于asp.net-mvc-4–MVC4–如何渲染视图字符串
对于想了解在Spring MVC中渲染视图时如何处理抛出的异常?的读者,本文将提供新的信息,我们将详细介绍spring mvc 视图,并且为您提供关于asp.net-mvc-4 – MVC4 – 如何渲染视图字符串?、java day62【 响应数据和结果视图 、 SpringMVC 实现文件上传 、 SpringMVC 中的异常处理 、 SpringMVC 中的拦截器 】、java – 如何处理过滤器中抛出的异常?、Spring boot 前后台分离项目 怎么处理spring security 抛出的异常的有价值信息。
本文目录一览:- 在Spring MVC中渲染视图时如何处理抛出的异常?(spring mvc 视图)
- asp.net-mvc-4 – MVC4 – 如何渲染视图字符串?
- java day62【 响应数据和结果视图 、 SpringMVC 实现文件上传 、 SpringMVC 中的异常处理 、 SpringMVC 中的拦截器 】
- java – 如何处理过滤器中抛出的异常?
- Spring boot 前后台分离项目 怎么处理spring security 抛出的异常
在Spring MVC中渲染视图时如何处理抛出的异常?(spring mvc 视图)
我有一个使用FreeMarker作为View技术的Spring
MVC应用程序(但是也许对我的问题来说,视图技术并不重要)。我需要拦截在请求期间可能引发的所有异常。
我已经实现了HandlerExceptionResolver,但是仅当控制器中发生异常时才执行此解析器。但是,当控制器返回ModelAndView且呈现视图时发生异常(因为未找到变量或类似的东西),则不调用异常解析器,而是在浏览器窗口中获取堆栈跟踪。
我还尝试在控制器中使用异常处理程序方法,该方法返回视图并使用@ExceptionHandler对其进行注释,但这也不起作用(很可能再次出现,因为异常不是在控制器中而是在视图中抛出)。
那么,是否有一些Spring机制可以注册捕获视图错误的异常处理程序?
答案1
小编典典一个简单的词:如果您只需要一个“静态”错误页面而没有太多的逻辑和模型准备,那么<error-page>
在您的页面中放置一个-Tag
就足够了web.xml
(请参见下面的示例)。
否则,可能会有更好的方法来执行此操作,但这对我们有用:
我们使用servlet<filter>
中web.xml
,捕捉所有的异常,并调用我们自定义的ErrorHandler,春节HandlerExceptionResolver内的,我们使用。
<filter> <filter-name>errorHandlerFilter</filter-name> <filter-class>org.example.filter.ErrorHandlerFilter</filter-class></filter><filter-mapping> <filter-name>errorHandlerFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
该实现基本上如下所示:
public class ErrorHandlerFilter implements Filter { ErrorHandler errorHandler; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { try { filterChain.doFilter(request, response); } catch (Exception ex) { // call ErrorHandler and dispatch to error jsp String errorMessage = errorHandler.handle(request, response, ex); request.setAttribute("errorMessage", errorMessage); request.getRequestDispatcher("/WEB-INF/jsp/error/dispatch-error.jsp").forward(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { errorHandler = (ErrorHandler) WebApplicationContextUtils .getRequiredWebApplicationContext(filterConfig.getServletContext()) .getBean("defaultErrorHandler"); } // ...}
我相信这对于FreeMarker模板应该几乎一样。当然,如果您的错误视图引发错误,那么您或多或少就会失去选择。
为了也捕获404之类的错误并为其准备模型,我们使用映射到ERROR
调度程序的过滤器:
<filter> <filter-name>errorDispatcherFilter</filter-name> <filter-class>org.example.filter.ErrorDispatcherFilter</filter-class></filter><filter-mapping> <filter-name>errorDispatcherFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>ERROR</dispatcher></filter-mapping><error-page> <error-code>404</error-code> <location>/WEB-INF/jsp/error/dispatch-error.jsp</location></error-page><error-page> <exception-type>java.lang.Exception</exception-type> <location>/WEB-INF/jsp/error/dispatch-error.jsp</location></error-page>
doFilter-Implementation如下所示:
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) servletRequest; // handle code(s) final int code = (Integer) request.getAttribute("javax.servlet.error.status_code"); if (code == 404) { final String uri = (String) request.getAttribute("javax.servlet.error.request_uri"); request.setAttribute("errorMessage", "The requested page ''" + uri + "'' could not be found."); } // notify chain filterChain.doFilter(servletRequest, servletResponse);}
asp.net-mvc-4 – MVC4 – 如何渲染视图字符串?
现有的答案对我没有帮助(可能是因为MVC版本的差异).
解决方法
https://coderwall.com/p/8ie5jg
using System.IO; using System.Web.Mvc; public class RenderRazorViewToString { #region Render public string Render( Controller controller,string viewName,object model ) { controller.ViewData.Model = model; using ( var sw = new StringWriter() ) { var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext,viewName); var viewContext = new ViewContext(controller.ControllerContext,viewResult.View,controller.ViewData,controller.TempData,sw); viewResult.View.Render(viewContext,sw); viewResult.ViewEngine.ReleaseView(controller.ControllerContext,viewResult.View); return sw.GetStringBuilder().ToString(); } } #endregion }
免责声明:我不是作者,我只是想分享它来帮助像我这样的其他人.
java day62【 响应数据和结果视图 、 SpringMVC 实现文件上传 、 SpringMVC 中的异常处理 、 SpringMVC 中的拦截器 】
第 1 章 响应数据和结果视图
1.1 返回值分类
1.1.1 字符串
1.1.2 void
1.1.3 ModelAndView
1.2 转发和重定向
1.2.1 forward 转发
1.2.2 Redirect 重定向
1.3ResponseBody 响应 json 数据
1.3.1 使用说明
1.3.2 使用示例
第 2 章 SpringMVC 实现文件上传
2.1 文件上传的回顾
2.1.1 文件上传的必要前提
2.1.2 文件上传的原理分析
2.1.3 借助第三方组件实现文件上传
2.2springmvc 传统方式的文件上传
2.2.1 说明
2.2.2 实现步骤
2.2.2.1 第一步:拷贝文件上传的 jar 包到工程的 lib 目录
2.2.2.2 第二步:编写 jsp 页面
2.2.2.3 第三步:编写控制器
2.2.2.4 第四步:配置文件解析器
2.3springmvc 跨服务器方式的文件上传
2.3.1 分服务器的目的
2.3.2 准备两个 tomcat 服务器,并创建一个用于存放图片的 web 工程
2.3.3 拷贝 jar 包
2.3.4 编写控制器实现上传图片
2.3.5 编写 jsp 页面
2.3.6 配置解析器
第 3 章 SpringMVC 中的异常处理
3.1 异常处理的思路
3.2 实现步骤
3.2.1 编写异常类和错误页面
3.2.2 自定义异常处理器
3.2.3 配置异常处理器
3.2.4 运行结果:
第 4 章 SpringMVC 中的拦截器
4.1 拦截器的作用
4.2 自定义拦截器的步骤
4.2.1 第一步:编写一个普通类实现 HandlerInterceptor 接口
4.2.2 第二步:配置拦截器
4.2.3 测试运行结果:
4.3 拦截器的细节
4.3.1 拦截器的放行
4.3.2 拦截器中方法的说明
4.3.3 拦截器的作用路径
4.3.4 多个拦截器的执行顺序
4.4 正常流程测试
4.4.1 配置文件:
4.4.2 拦截器 1 的代码:
4.4.3 拦截器 2 的代码:
4.4.4 运行结果:
4.5 中断流程测试
4.5.1 配置文件:
4.5.2 拦截器 1 的代码:
4.5.3 拦截器 2 的代码:
4.5.4 运行结果:
4.6 拦截器的简单案例(验证用户是否登录)
4.6.1 实现思路
4.6.2 控制器代码
4.6.3 拦截器代码
java – 如何处理过滤器中抛出的异常?
到目前为止,我在过滤器的HTTPResponse中手动将状态设置为403.有没有更好的处理这种情况的方法?
解决方法
you should use something like this
在web.xml中设置错误处理程序
<error-page> <exception-type>java.lang.RuntimeException</exception-type> <location>/handleExceptionService</location> </error-page>
所以,当你达到你的服务,你可以做你想要的错误.
祝你好运!!!
Spring boot 前后台分离项目 怎么处理spring security 抛出的异常
最近在开发一个项目 前后台分离的 使用 spring boot + spring security + jwt 实现用户登录权限控制等操作。但是 在用户登录的时候,怎么处理spring security 抛出的异常呢?使用了@RestControllerAdvice 和@ExceptionHandler 不能处理Spring Security抛出的异常,如 UsernameNotFoundException等,我想要友好的给前端返回提示信息 如,用户名不存在之类的。 贴上我的代码:
JWT 验证类 : 重写了spring security UsernamaPasswordAuthenticationFilter
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private AuthenticationManager authenticationManager; private RedisServiceImpl redisService; private AppConfig appConfig; public JWTAuthenticationFilter(AuthenticationManager authenticationManager, RedisServiceImpl redisService, AppConfig appConfig) { this.authenticationManager = authenticationManager; this.redisService = redisService; this.appConfig = appConfig; } /** * @param req * @param res * @return * @throws AuthenticationException * @// TODO: 2018/4/12 接受并解析用户凭证 */ @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException { try { AuthEntity creds = new ObjectMapper() .readValue(req.getInputStream(), AuthEntity.class); //验证码校验 if (appConfig.getCaptchaEnabled()) { //如果开启了验证码登录校验功能 if (StringUtils.isBlank(creds.getCaptcha())) { logger.error("验证码为空"); throw new WelendException(StatusCode.CAPTCHA_EMPTY); } if (!redisService.exists(appConfig.getCaptchaKey())) { logger.error("验证码已失效"); throw new WelendException(StatusCode.CAPTCHA_OVERDUE); } String captcha = (String) redisService.get(appConfig.getCaptchaKey()); if (!creds.getCaptcha().equals(captcha)) { logger.error("验证码不正确"); throw new WelendException(StatusCode.CAPTCHA_ERROR); } } return authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( creds.getUsername(), creds.getPassword(), new ArrayList<>()) ); } catch (IOException e) { logger.error("Client''s variables can''t be parsed by com.fasterxml.jackson.core.JsonParse"); throw new WelendException(StatusCode.SERVER_ERROR); } } }
验证用户名 密码:
public class CustomAuthenticationProvider implements AuthenticationProvider { private UserDetailsServiceImpl userDetailsService; private BCryptPasswordEncoder bCryptPasswordEncoder; public CustomAuthenticationProvider(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) { this.userDetailsService = userDetailsService; this.bCryptPasswordEncoder = bCryptPasswordEncoder; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 获取认证的用户名 & 密码 String name = authentication.getName(); String password = authentication.getCredentials().toString(); // 认证逻辑 JWTUserDetails userDetails = userDetailsService.loadUserByUsername(name); if (null != userDetails) { Boolean verifyPwd = bCryptPasswordEncoder.matches(password,userDetails.getLoginPwd()); if (verifyPwd) { // 生成令牌 这里令牌里面存入了:userDetails,password,authorities(权限列表) Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); return auth; } else { throw new BadCredentialsException("username or password wrong!"); } } else { throw new UsernameNotFoundException("can not find this account"); } } /** * 是否可以提供输入类型的认证服务 * @param authentication * @return */ @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }
全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* @param request
* @param exception
* @return
* @throws Exception
* @// TODO: 2018/4/25 参数未通过验证异常
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class) public Object MethodArgumentNotValidHandler(HttpServletRequest request, MethodArgumentNotValidException exception) throws Exception { //按需重新封装需要返回的错误信息 //List<StatusCode> invalidArguments = new ArrayList<>(); //解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息 ResultObject resultMsg = ResultObject.dataMsg(exception.getBindingResult().getFieldError().getDefaultMessage(), StatusCode.VARIABLE_ERROR); return resultMsg; } /** * @param request * @param exception * @return * @throws Exception * @// TODO: 2018/4/25 无法解析参数异常 */ @ExceptionHandler(value = HttpMessageNotReadableException.class) public Object HttpMessageNotReadableHandler(HttpServletRequest request, HttpMessageNotReadableException exception) throws Exception { logger.info(exception.getMessage()); ResultObject resultMsg = ResultObject.dataMsg("参数无法正常解析", StatusCode.VARIABLE_ERROR); return resultMsg; } /** * @param exception * @return * @throws Exception * @// TODO: 2018/4/25 处理token 过期异常 */ @ExceptionHandler(value = ExpiredJwtException.class) public Object ExpiredJwtExceptionHandler(ExpiredJwtException exception) throws Exception { logger.info(exception.getMessage()); ResultObject resultMsg = ResultObject.dataMsg("登录已过期!", StatusCode.FORBIDDEN); return resultMsg; } /** * @param request * @param exception * @return * @throws Exception * @// TODO: 2018/4/25 方法访问权限不足异常 */ @ExceptionHandler(value = AccessDeniedException.class) public Object AccessDeniedExceptionHandler(AccessDeniedException exception) throws Exception { logger.info(exception.getMessage()); ResultObject resultMsg = ResultObject.dataMsg("权限不足!", StatusCode.FORBIDDEN); return resultMsg; } @ExceptionHandler(value = NoHandlerFoundException.class) public Object NoHandlerFoundExceptionHandler(NoHandlerFoundException exception) throws Exception { logger.info(exception.getMessage()); return ResultObject.dataMsg("链接不存在", StatusCode.NOT_FOUND); } /** * 处理自定义异常 */ @ExceptionHandler(value = WelendException.class) public Object WelendExceptionHandler(WelendException e) { ResultObject r = new ResultObject(); r.setStatus(String.valueOf(e.getCode())); r.setMessage(e.getMessage()); return r; } @ExceptionHandler(value = AuthenticationException.class) public Object AuthenticationExceptionHandler(AuthenticationException e) { return ResultObject.dataMsg(e.getLocalizedMessage(),StatusCode.FORBIDDEN); } @ExceptionHandler(value = DuplicateKeyException.class) public Object DuplicateKeyExceptionHandler(DuplicateKeyException e) throws Exception { logger.error(e.getMessage(), e); return ResultObject.codeMsg(StatusCode.EXISTED); } @ExceptionHandler(value = BadCredentialsException.class) public Object BadCredentialsExceptionHandler(BadCredentialsException e) throws Exception { logger.error(e.getMessage(), e); return ResultObject.codeMsg(StatusCode.AUTH_ERROR); } @ExceptionHandler(value = Exception.class) public Object ExceptionHandler(Exception e) throws Exception { logger.error(e.getMessage(), e); return ResultObject.codeMsg(StatusCode.FAILED); } }
登录时输入错误的用户名
控制台直接打印信息了, 并没有经过ExceptionHandler 处理。
如上所示,我想在全局异常类中 处理spring security抛出异常, 以便返回友好的提示信息。有什么解决办法么?
关于在Spring MVC中渲染视图时如何处理抛出的异常?和spring mvc 视图的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于asp.net-mvc-4 – MVC4 – 如何渲染视图字符串?、java day62【 响应数据和结果视图 、 SpringMVC 实现文件上传 、 SpringMVC 中的异常处理 、 SpringMVC 中的拦截器 】、java – 如何处理过滤器中抛出的异常?、Spring boot 前后台分离项目 怎么处理spring security 抛出的异常等相关知识的信息别忘了在本站进行查找喔。
本文标签: