文章目录
- 一、项目环境搭建及测试
- 二、安装Zookeeper
- 三、Maven打包及项目启动引发的各种错误
- 1、Maven打包install:The packaging for this project did not assign a file to the build artifact
- 2、No mapping found for HTTP request with URI [/brand/findAll.do] in DispatcherServlet with name 'springmvc'
- 3、解决maven打包编译出现File encoding has not been set问题
- 4、'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing版本号丢失
- 5、tomcat启动报错:Invalid byte tag in constant pool: 19
- 6、Hessian/Burlap: 'com.github.pagehelper.Page' is an unknown class in TomcatEmbeddedWebappClassLoader
- 四、全局异常处理
- 五、文件上传功能的实现
一、项目环境搭建及测试
1、模块化开发
公共模块搭建
- 创建父模块,利用
<dependencyManagement>
进行依赖管理,只是控制依赖的版本,并没有真正引入依赖。直接用<dependencies>
包裹的依赖是公用的。 - 创建公共模块(第二级),
qc-common
,引入Spring等相关公共依赖。 - 创建公共模块的子模块(第三级),
qc-common-service
:公共服务模块,引入mybatis,mysql等模块。qc-common-web
:公共web模块,引入安全模块,文件上传模块等。qc-pojo
:实体模块,引入jpa依赖。qc-interface
:接口模块,引入qc-pojo
服务模块搭建
- 创建
qc-service-goods
模块,将打包方式改为<packaging>war</packaging>
。 - 引入两个公共模块,
qc-interface
和qc-common-service
。需要注意的是,由于具有传递性,俩模块中的配置都可以被服务模块读取到。 - 引入tomcat插件,注意之后的每个需要tomcat插件的端口号需要不同。
- 在main目录下创建webapp,在之中创建WEB-INF/web.xml,用于加载spring配置文件。
web模块搭建
- 创建
qc-web-manager
模块,将打包方式改为<packaging>war</packaging>
。 - 引入两个公共模块,
qc-interface
和qc-common-web
。需要注意的是,由于具有传递性,俩模块中的配置都可以被服务模块读取到。 - 引入tomcat插件,注意之后的每个需要tomcat插件的端口号需要不同。
- 在main目录下创建webapp,在之中创建WEB-INF/web.xml,用于加载spring配置文件。
2、编写简单demo测试
编写实体类
在qc-pojo
中编写实体类
@Table(name = "tb_brand")
public class Brand implements Serializable {
@Id
private Integer id;
private String name;
private String image;
private String letter;
private Integer seq;
//省略getter和setter
}
编写mapper继承通用Mapper
在qc-service-goods
中编写mapper。
/**
* 继承通用Mapper,具有增删改查的基本方法
* @author Summerday
*/
public interface BrandMapper extends Mapper<Brand> {
}
编写Service接口和实现类
在qc-interface
中编写Service接口,在qc-service-goods
中编写实现类。
public interface BrandService {
public List<Brand> findAll();
}
@Service //com.alibaba.dubbo.config.annotation.Service
public class BrandServiceImpl implements BrandService {
@Autowired
private BrandMapper brandMapper;
@Override
public List<Brand> findAll() {
return brandMapper.selectAll();
}
}
编写控制器
在qc-web-manager
中编写控制器
@RestController
@RequestMapping("/brand")
public class BrandController {
@Reference //调用远程接口用@Reference
private BrandService brandService;
@RequestMapping("/findAll")
public List<Brand> findAll(){
return brandService.findAll();
}
}
二、安装Zookeeper
-
将conf目录下的zoo_sample.cfg改名为zoo.cfg。
-
修改zoo.cfg文件的配置,设置数据和日志存放的路径。
dataDir=E:\\Java\\zookeeper-3.4.13\\datas dataLogDir=E:\\Java\\zookeeper-3.4.13\\logs
-
配置JAVA_HOME
-
双击zkServer.cmd启动。
三、Maven打包及项目启动引发的各种错误
1、Maven打包install:The packaging for this project did not assign a file to the build artifact
参考:https://blog.csdn.net/Camellia919/article/details/81190450
选择LifeCycle中的install即可,因为该操作将会自动去maven仓库下载需要的包。
2、No mapping found for HTTP request with URI [/brand/findAll.do] in DispatcherServlet with name ‘springmvc’
- 查看请求的url是否与设置的requestMapping("/findAll")相同。
- 查看是否正确扫描controller包。
<context:component-scan base-package="com.qingcheng.controller"/>
。
3、解决maven打包编译出现File encoding has not been set问题
在pom.xml中加入以下内容:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
4、‘build.plugins.plugin.version’ for org.apache.maven.plugins:maven-compiler-plugin is missing版本号丢失
build.plugins.plugin
版本号缺失,为该插件加上版本号即可。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
5、tomcat启动报错:Invalid byte tag in constant pool: 19
严重: Unable to process Jar entry [module-info.class] from Jar [jar:file:/E:/Java/maven_repository/org/projectlombok/lombok/1.18.12/lombok-1.18.12.jar!/] for annotations
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19
参考:https://blog.csdn.net/kinder10314/article/details/86629992,该博客描述非常详细,可以参看。
- 将lombok的scope改为provided。(可行)
- 修改tomcat的版本。(未尝试)
6、Hessian/Burlap: ‘com.github.pagehelper.Page’ is an unknown class in TomcatEmbeddedWebappClassLoader
参考:https://blog.csdn.net/u011403655/article/details/91045441
四、全局异常处理
/**
* 全局异常处理
*
* @author Summerday
*/
@ControllerAdvice
public class BaseExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(BaseExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
logger.warn(e.getMessage());
return new Result(1, e.getMessage());
}
}
五、文件上传功能的实现
1、前端功能实现
ElementUI图片上传组件
<body>
<div >
<el-form-item label="品牌图片">
<el-upload
class="avatar-uploader"
action="/upload/native.do"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</div>
</body>
<script>
new Vue({
el: '#app',
data () {
return {
imageUrl: ''
}
},
created () {
this.fetchData()
},
methods: {
handleAvatarSuccess(res, file) {
//成功之后的方法
this.imageUrl = file.response;
},
beforeAvatarUpload(file) {
//上传之前对文件校验的勾子方法
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
}
}
})
</script>
2、后端代码实现
SpringMVC文件本地上传
springmvc.xml注册一个CommonsMultipartResolver。(Servlet3.0,Spring3.1之后可以使用更优秀的StandardServletMultipartResolver)
<!-- 多部分文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600" />
<property name="maxInMemorySize" value="4096" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
编写处理文件上传请求的控制器,SpringMvc接受一个MultipartFile对象并存储到我们指定的路径上。
/**
* 文件上传控制器
*
* @author Summerday
*/
@RestController
@RequestMapping("/upload")
public class UploadController {
@Autowired
private HttpServletRequest request;
@PostMapping("/native")
public String nativeUpload(@RequestParam("file") MultipartFile file) {
//本地服务器项目路径
String path = request.getSession().getServletContext().getRealPath("img");
String filePath = path + "/" + file.getOriginalFilename();
// 创建文件对象
File destFile = new File(filePath);
if (!destFile.getParentFile().exists()){
destFile.mkdirs();
}
try {
//存储
file.transferTo(destFile);
} catch (IOException e) {
e.printStackTrace();
}
return "http://localhost:9101/img/"+file.getOriginalFilename();
}
}
阿里云对象存储oss实现图片存储
https://help.aliyun.com/document_detail/32011.html?spm=a2c4g.11186623.6.789.554f6328vNnvNU
引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
配置必要信息
oss.endpoint=oss-cn-hangzhou.aliyuncs.com
oss.accessKeyId =<accessKeyId>
oss.accessKeySecret =<accessKeySecret>
配置ossClient实例
<!--阿里云OSS -->
<bean id="ossClient" class="com.aliyun.oss.OSSClient">
<constructor-arg index="0" value="${oss.endpoint}"/>
<constructor-arg index="1" value="${oss.accessKeyId}"/>
<constructor-arg index="2" value="${oss.accessKeySecret}"/>
</bean>
具体代码实现
@PostMapping("/oss")
public String ossUpload(@RequestParam("file") MultipartFile file, String folder){
String bucketName = "smday-oss";
//folder便于管理,UUID防止图片名相同覆盖
String objectName = folder+"/"+UUID.randomUUID()+file.getOriginalFilename();
try {
ossClient.putObject(bucketName,objectName,file.getInputStream());
} catch (IOException e) {
logger.warn(e.getMessage());
}
return "https://"+bucketName+".oss-cn-hangzhou.aliyuncs.com/"+objectName;
}