SpringBoot8 -- 整合JSP

学习笔记:

Springboot默认支持模板引擎,不支持jsp,当然,也建议大家都是用模板(Freemaker、Thymeleaf 、 Velocity等),jsp只能将项目打成war包才能使用,而且以后的趋势是前后端分离。

第一步:引入依赖

<!-- servlet 依赖包 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- JSTL (JSP standard Tag Library) JSP 标准标签库 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
<!-- 对jsp的支持 -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

第二步:在application.properties文件中添加前缀和后缀配置

#页面默认前缀目录
spring.mvc.view.prefix=/WEB-INF/jsp/
#页面默认后缀目录
spring.mvc.view.suffix=.jsp

第三步:编写控制层

@Controller
public class LoginController {
    @RequestMapping("login")
    public String login(@RequestParam("password") String password,@RequestParam("password2") String password2){
        if (StringUtils.equalsIgnoreCase(password,password2)){
            return "/success";
        }
        return "/error";
    }
}

第四步:编写jsp页面(代码很简单,仅限于模拟)

<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
    <title>My first Spring boot web demo</title>
</head>
<body>
<h2>success</h2>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
    <title>My first Spring boot web demo</title>
</head>
<body>
<h2>Error</h2>
</body>
</html>

第五步:测试

http://127.0.0.1:8080/login?password=123456&password2=1234561


http://127.0.0.1:8080/login?password=123456&password2=123456



到这里,springboot中集成jsp功能就结束了。但是我在测试集成的时候遇到了一个问题,就是如果控制层这样写

@Controller
public class LoginController {
    @RequestMapping("login")
    public String login(@RequestParam("password") String password,@RequestParam("password2") String password2){
        if (StringUtils.equalsIgnoreCase(password,password2)){
            return "success";
        }
        return "error";// 注意:这里没有加 /
    }
}

返回error页面时,没有加/,就会报错,错误如下


在springboot中,有一个类BasicErrorController,用于同一处理全局异常,当页面发生异常的时候回自动将请求转发到/error页面,这是springboot默认提供的一个映射。查看源码,


@RequestMapping("${server.error.path:${error.path:/error}}")

@RequestMapping(produces = "text/html")
public ModelAndView errorHtml(HttpServletRequest request,
      HttpServletResponse response) {
   HttpStatus status = getStatus(request);
   Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
         request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
   response.setStatus(status.value());
   ModelAndView modelAndView = resolveErrorView(request, response, status, model);
   return (modelAndView != null ? modelAndView : new ModelAndView("error", model)); 
}
在这里找到了原因,因为springboot默认了一个视图error。。。但是我依然不明白返回/error就能找到我自己的jsp,返回error就找它的

这个类里根据自动配置类ErrorMvcAutoConfiguration中

@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
   return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
         this.errorViewResolvers);
}

上面这段代码意思就是如果没有定义ErrorController时,这段代码生效,换言之,如果我们自定义了ErrorController这段代码,这段代码就不会自动配置了。一般来说,我们都需要定制化返回的错误信息,这个时候就需要重写BasicErrorController,继承重写error和errorHtml方法即可。

@Controller
public class MyErrorController extends BasicErrorController {

//    public MyErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
//        super(errorAttributes, errorProperties);
//    }


    public MyErrorController(ServerProperties serverProperties) {
        super(new DefaultErrorAttributes(), serverProperties.getError());
    }

    /**
     * 改写默认返回的HTML
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        // 请求状态
        HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
                request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        //改写默认错误视图
        return (modelAndView != null ? modelAndView : new ModelAndView("error", model));
    }

    /**
     * 改写默认返回的json
     *
     * @param request
     * @return
     */
    @Override
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        HttpStatus status = getStatus(request);
        Map<String, Object> map = new HashMap<>();
        map.put("message", "哦豁,出现了错误,请稍后重试");
        map.put("status", false);
        return new ResponseEntity<>(map, status);
    }
}

上面只是改变了返回的内容而已,但是怎么改变返回的不是默认的error处理呢

第一种办法:

在application.properties中添加

#server.error.path=/WEB-INF/jsp/error.jsp

第二种办法

指定错误页面来改写默认的错误页面,在或者在自定义的Controller上修改映射和produces指定映射地址

@RequestMapping("${server.error.path:${error.path:/myerror}}")

这两种办法一样的

但是对于error和/error依然困惑着,以后希望有人能够解答下。

----------------------------------------------------------------------------------------------------------------------

此外,对于全局异常处理,springboot也提供了@ControllerAdvice注解

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 全局异常处理
     *
     * @param e        RuntimeException
     * @param response HttpServletResponse
     * @return error JSONResult
     */
    @ExceptionHandler(RuntimeException.class)
    public JSONResult globalException(RuntimeException e, HttpServletResponse response) {
        logger.error(e.getMessage(), e);
        return ResultUtil.error(ResultCode.FAIL.getCode(), "操作失败");
    }

    /**
     * 非法登录异常处理
     * @param e
     * @param response
     * @return
     */
    @ExceptionHandler(IllegalAccessException.class)
    public JSONResult illegalAccessException(IllegalAccessException e, HttpServletResponse response) {
        logger.error(e.getMessage(), e);
        return ResultUtil.error(ResultCode.NO_VISIT_RIGHT.getCode(), e.getMessage());
    }
}

可以监测所有的RuntimeException,也可以自定义异常如IllegalAccessException

/**
 * 非法登录异常
 */
public class IllegalAccessException extends RuntimeException {
    public IllegalAccessException() {
    }

    public IllegalAccessException(String message) {
        super(message);
    }
}

@ControllerAdvice可以设置参数,监测某些路径下的控制器,也可以指定特定控制器类型等。

也可以自定义AOP拦截处理异常。

猜你喜欢

转载自blog.csdn.net/qq_36781718/article/details/80555494
今日推荐