一、当springboot遇到JSP
1、通过SpringMVC的@Controller控制访问jsp页面但总是找不到对应页面
前文提要:做WEB项目,一定都用过JSP这个大牌。Spring MVC里面也可以很方便的将JSP与一个View关联起来,使用还是非常方便的。当你从一个传统的Spring MVC项目转入一个Spring Boot项目后,却发现JSP和view关联有些麻烦,因为官方不推荐JSP在Spring Boot中使用。好吧,我也不知道为什么官方会这样对待jsp
【出错的原代码】下面展示下我的项目结构和代码
项目结构(主要关注我标红的这处)
我的pom文件(tomcat 的支持;这里是必须的,但我先临时注掉因为启动会报错,我稍后会解决这一问题)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.marvin.demo</groupId>
<artifactId>springboot_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springboot_demo Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<!-- Spring boot 父引用-->
<!--继承Spring Boot默认配置-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.RELEASE</version>
</parent>
<dependencies>
<!--添加第一个Boot Web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加database-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<!-- jsp依赖支持的支持;这里是必须的,但我先临时注掉会面会解释为什么加它-->
<!--<dependency>-->
<!--<groupId>org.apache.tomcat.embed</groupId>-->
<!--<artifactId>tomcat-embed-jasper</artifactId>-->
<!--<scope>provided</scope>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>springboot_demo</finalName>
<plugins>
<!--配置boot运行插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
application.properties
#spring mvc页面配置
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
server.port=8080
启动程序
@SpringBootApplication
@PropertySource("classpath:application.properties")//定义资源文件,默认application.properties
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
控制层类
@Controller
public class Login {
@Resource
private UserService userServiceImpl;
public void setUserServiceImpl(UserService userServiceImpl) {
this.userServiceImpl = userServiceImpl;
}
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){
System.out.println("login method");
return "index";
}
}
出现的问题分析及解决方案
1、项目启动,运行Application里面的main方法
发现问题:界面报错404,说找不到页面;但控制台确实打印了login()方法内的输出
分析:
- 说明我们的请求确实已经发送至后台,并且执行了正确的方法,所以进入请求这里是正确的,那么可能是返回的ModelAndView出现了问题(检查返回参数路径和配置的前后置拼接是否存在问题)
- 检查路径和返回页面名确实没有任何问题。我在网上查到springboot似乎对JSP的限制比较大,所以需要在pom文件中添加对jsp支持的依赖
解决方案:
在pom文件中引入对jsp的支持的依赖
使用过Springboot的同学都知道其已内置tomcat(spring-boot-starter-web依赖中包含了spring-boot-starter-tomcat),无需打war包,打成jar包直接运行。最近学习使用Springboot发现项目中的pom文件引入了tomcat-embed-jasper(对jsp的支持的依赖)
spring-boot-starter-web包含了spring-boot-starter-tomcat,这个包里有tomcat-embed-core、tomcat-embed-el,前者包含servlet-api和内置servlet容器,后者为el表达式包。但是很可惜,Tomcat这个依赖中并被没有包含tomcat-embed-jasper。
值得注意的是这里的<scope>一定不能是provided,需要时默认的,所以我注掉了
如果scope为provided的话,打包没有加进去,那tomcat-embed-jasper的引入有什么用呢
<!--jsp依赖支持-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!--<scope>provided</scope>-->
</dependency>
二、“程序包XXX不存在”多模块中相互引用编译报错
1、遇到的问题
pchat-center子模块要导入 pchat-user 的jar包
pchat-center的pom文件如下:
pchat-center子模块包依赖了pchat-user子模块包
代码如下:
代码没显示任务异常,没有标红显示。
maven编译结果如下:
明明引入了pchat-user包,而且显示成功引入了,maven本地库也有这个jar包
2、错误原因是pchat-user打包方式不对。
spring-boot maven打包,一般pom.xml文件里会加
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
引起问题,程序包不存在。
这样打的jar里会多一个目录BOOT-INF。(反编译工具打开)
3、解决方案
如果 A 子模块包依赖了 B 子模块包,在被依赖的 B 子模块的pom文件,加入 <skip>true</skip>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
目录BOOT-INF没有了