微框架spring boot
什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。 为什么要使用spring boot Spring IO大量的XML配置以及复杂的依赖管理一直是其饱受非议的一点。而Boot的实现不仅仅实现了免XML配置的开发体验,而且在一些场景中甚至不需要编写繁琐的import语句。Spring Boot的目标不在于为已解决的问题域提供新的解决方案,而是为平台带来另一种开发体验,从而简化对这些已有技术的使用。对于已经熟悉Spring生态系统的开发人员来说,Boot是一个很理想的选择,不过对于采用Spring技术的新人来说,Boot提供一种更简洁的方式来使用这些技术。 使用Spring Boot 要进行打包和分发的工程会依赖于像 Maven或 Gradle这样的构建系统。为了简化依赖图,Boot的功能是模块化的,通过导入Boot所谓的“starter”模块,可以将许多的依赖添加到工程之中。官方网站给我们提供了集成相关服务的项目例子,我们直接下载 https://start.spring.io/。 为了更容易地管理依赖版本和使用默认配置,框架提供了一个parent POM,工程可以继承它。Spring Boot工程的样例POM文件定义如下所示: [html] view plain copy <?xmlversion="1.0"encoding="UTF-8"?> <projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.2-SNAPSHOT</version> <!--Boot默认打包为jar--> <packaging>war</packaging> <name>demo</name> <description>DemoprojectforSpringBoot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath/><!--lookupparentfromrepository--> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--这里指定打包的时候不再需要tomcat相关的包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <!--打包时需要添加以下依赖--> <!--<scope>provided</scope>--> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--SpringBootJDBC--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <!--optional=true,依赖不会传递,该项目依赖devtools;之后依赖myboot项目的项目如果想要使用devtools,需要重新引入--> <optional>true</optional> </dependency> <!--整合cxf--> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.6</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.1.6</version> </dependency> <!--HikariCP依赖--> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <!--版本号可以不用指定,SpringBoot会选用合适的版本--> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!--分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.0</version> </dependency> <!--httpclient--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient-cache</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.1.2</version> </dependency> <!--json-lib--> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <!--加入静态文件和jsp--> <!--对jsp的支持--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <!--打包时需要添加以下依赖--> <!--<scope>provided</scope>--> </dependency> <!--配置servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <!--MYSQL--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.7</version> <scope>system</scope> <systemPath>${basedir}/src/lib/mysql-connector-java-5.1.7-bin.jar</systemPath> </dependency> <!--添加外部依赖--> <dependency> <groupId>Ice</groupId> <artifactId>Ice</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${basedir}/src/lib/jsonrpc4j-0.27.jar</systemPath> </dependency> <!--<!–https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api–>--> <!--<dependency>--> <!--<groupId>javax.xml.bind</groupId>--> <!--<artifactId>jaxb-api</artifactId>--> <!--<version>2.2.11</version>--> <!--</dependency>--> </dependencies> <build> <plugins> <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> <skip>true</skip> </configuration> </plugin> <!--maven打包的时候告诉maven不需要web.xml,否刚会报找不到web.xml错误--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <!--将外部依赖打入war包的lib目录下--> <webResources> <resource> <directory>src/lib</directory> <targetPath>WEB-INF/lib/</targetPath> <includes> <include>**/*.jar</include> </includes> </resource> </webResources> </configuration> </plugin> </plugins> <!--手工设置resource--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*</include> </includes> </resource> <resource> <directory>src/main/webapp</directory> <includes> <include>**/*</include> </includes> </resource> </resources> </build> </project> 构建Boot web应用 1.在配置文件中引入Spring Boot的web依赖: [html] view plain copy <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> spring-boot-starter-web 包含了很多内容,spring-webmvc、spring-web、jackson、validation、tomcat、starter。 2.开始编写代码,由于Maven默认编译路径为 src/main/java 下面的源码,所以,默认设置下,需要创建一些文件夹。 编写文件src\main\java\com\example\hello\HelloController.java: [html] view plain copy packagecom.example.hello; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RequestParam; importorg.springframework.web.bind.annotation.RestController; importjava.util.Map; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.List; /** *Createdbywuhaochaoon2017/7/12. */ @RestController @RequestMapping("/hello") publicclassHelloController{ @RequestMapping("/index") publicStringindex(@RequestParamStringname){ //return"helloword"+name; return"index"; } @RequestMapping("/info") publicMap<String,String>getInfo(@RequestParamStringname){ Map<String,String>map=newHashMap<>(); map.put("name",name); returnmap; } @RequestMapping("/list") publicList<Map<String,String>>getList(){ List<Map<String,String>>list=newArrayList<>(); Map<String,String>map=null; for(inti=1;i<=5;i++){ map=newHashMap<>(); map.put("name","Shanhy-"+i); list.add(map); } returnlist; } } @RestController因为我们例子是写一个web应用,因此写的这个注解,这个注解相当于同时添加@Controller和@ResponseBody注解。 创建一个Application类: [html] view plain copy packagecom.example; importorg.apache.cxf.transport.servlet.CXFServlet; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.boot.builder.SpringApplicationBuilder; importorg.springframework.boot.web.servlet.ServletComponentScan; importorg.springframework.boot.web.servlet.ServletRegistrationBean; importorg.springframework.boot.web.support.SpringBootServletInitializer; importorg.springframework.context.annotation.Bean; importorg.springframework.scheduling.annotation.EnableAsync; importorg.springframework.scheduling.annotation.EnableScheduling; importorg.springframework.transaction.PlatformTransactionManager; importorg.springframework.transaction.annotation.EnableTransactionManagement; importorg.springframework.web.context.support.AnnotationConfigWebApplicationContext; importorg.springframework.web.servlet.DispatcherServlet; //@EnableScheduling//启动定时探测 @EnableAsync//启动自定义线程池 @EnableTransactionManagement//启动事物管理 @SpringBootApplication publicclassDemoApplicationextendsSpringBootServletInitializer{ @Override protectedSpringApplicationBuilderconfigure(SpringApplicationBuilderapplication){ returnapplication.sources(DemoApplication.class); } @Bean publicServletRegistrationBeanrestServlet(){ //注解扫描上下文 AnnotationConfigWebApplicationContextapplicationContext=newAnnotationConfigWebApplicationContext(); //basepackage这里指定到controller不指定*,因为配置有定时任务,容易造成bean冲突,导致定时任务执行2次 applicationContext.scan("com.example.controller"); ///通过构造函数指定dispatcherServlet的上下文 DispatcherServletrest_dispatcherServlet=newDispatcherServlet(applicationContext); //用ServletRegistrationBean包装servlet ServletRegistrationBeanregistrationBean=newServletRegistrationBean(rest_dispatcherServlet); registrationBean.setLoadOnStartup(1); //指定urlmapping registrationBean.addUrlMappings("/webapp/*"); //指定name,如果不指定默认为dispatcherServlet registrationBean.setName("webapp"); returnregistrationBean; } @Bean publicObjecttestBean(PlatformTransactionManagerplatformTransactionManager){ System.out.println(">>>>>>>>>>>>>>>>>"+platformTransactionManager.getClass().getName()+"<<<<<<<<<<<<<<<<<<<<<"); returnnewObject(); } publicstaticvoidmain(String[]args){ SpringApplication.run(DemoApplication.class,args); } }<strong> </strong> 注意Spring Boot建议将我们main方法所在的这个主要的配置类配置在根包src名下。继承SpringBootServletIntializer和方法configure是后期为实现跳转前端页面的配置。 启动项目就可以在浏览器访问了。 数据访问 在配置文件application.properties中配置数据源: [html] view plain copy #数据源设置 spring.datasource.url=jdbc:mysql://localhost:3306/stu_info spring.datasource.username=root spring.datasource.password=111111 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.max-idle=10 #指定连接池等待连接返回的最大等待时间,毫秒单位. spring.datasource.max-wait=10000 #指定必须保持连接的最小值 spring.datasource.min-idle=5 #指定连接池中最大的活跃连接数. spring.datasource.secondary.max-active=50 spring.datasource.initial-size=5 spring.datasource.validation-query=SELECT1 spring.datasource.test-on-borrow=false spring.datasource.test-while-idle=true spring.datasource.time-between-eviction-runs-millis=18800 spring.datasource.jdbc-interceptors=ConnectionState;SlowQueryReport(threshold=0) #mybatis数据文件路径 mybatis.mapper-locations=com/example/mapper/sql/*Mapper.xml mybatis.type-aliases-package=com.example.entity 添加mybatis相关依赖: [html] view plain copy <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!--分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.0</version> </dependency> 编写mybatis: [html] view plain copy packagecom.example.mapper; importcom.example.entity.TranscationBean; importorg.apache.ibatis.annotations.Mapper; importorg.apache.ibatis.annotations.Param; importjava.util.List; /** *Createdbywuhaochaoon2017/7/24. */ @Mapper publicinterfaceTranscationMapper{ //获取交易信息 List<TranscationBean>getTranscation(); //插入交易信息 intinsertTranscationBean(@Param("transcationBean")TranscationBeantranscationBean); //批量插入交易信息 intinsertTranscationList(@Param("transcationList")List<TranscationBean>transcationList); } 对于的xml文件: [html] view plain copy <?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mappernamespace="com.example.mapper.TranscationMapper"> <!--type为实体类TranscationBean,包名已经配置,可以直接写类名--> <resultMapid="transcationMap"type="TranscationBean"> <idproperty="hash"column="transactionHash"/> <resultproperty="transactionIndex"column="transactionIndex"/> <resultproperty="blockHash"column="blockHash"/> <resultproperty="blockNumber"column="blockNumber"/> <resultproperty="from"column="from"/> <resultproperty="to"column="to"/> <resultproperty="nonce"column="nonce"/> <resultproperty="gasPrice"column="gasPrice"/> <resultproperty="gas"column="gas"/> <resultproperty="input"column="input"/> <resultproperty="value"column="value"/> <resultproperty="timestamp"column="timestamp"/> </resultMap> <!--查询最新交易信息--> <selectid="getTranscation"resultMap="transcationMap"resultType="TranscationBean"> select*fromtransaction_infotorderbyt.TIMESTAMPdesc </select> <!--批量插入交易信息--> <insertid="insertTranscationList"parameterType="java.util.List"> insertintotransaction_infoVALUES <foreachcollection="transcationList"item="trsList"index="index"open="("close=")"separator=","> #{trsList.hash},#{trsList.transactionIndex},#{trsList.blockHash}, #{trsList.blockNumber},#{trsList.from},#{trsList.to}, #{trsList.nonce},#{trsList.gasPrice},#{trsList.gas}, #{trsList.input},#{trsList.value},#{trsList.timestamp} </foreach> </insert> <!--插入交易信息--> <insertid="insertTranscation"parameterType="TranscationBean"> insertintotransaction_infoVALUES( #{hash},#{transactionIndex},#{blockHash}, #{blockNumber},#{from},#{to}, #{nonce},#{gasPrice},#{gas}, #{input},#{value},#{timestamp} ) </insert> </mapper> 配置mybatis分页插件: [html] view plain copy packagecom.example.mapper; importcom.github.pagehelper.PageHelper; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importjava.util.Properties; /** *Createdbywuhaochaoon2017/7/21. */ @Configuration publicclassMyBatisConfiguration{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(MyBatisConfiguration.class); @Bean publicPageHelpergeHelper(){ logger.info("注册mybatis分页插件"); PageHelperpageHelper=newPageHelper(); Propertiesproperties=newProperties(); properties.setProperty("offsetAsPageNum","true"); properties.setProperty("rowBoundsWithCount","true"); properties.setProperty("reasonable","true"); pageHelper.setProperties(properties); returnpageHelper; } } 控制层调用: [html] view plain copy packagecom.example.controller; importcom.example.entity.TranscationBean; importcom.example.mapper.TranscationMapper; importcom.example.unitl.Until; importcom.fasterxml.jackson.databind.ObjectMapper; importcom.github.pagehelper.PageHelper; importcom.github.pagehelper.PageInfo; importnet.sf.json.JSONArray; importnet.sf.json.JSONObject; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.PathVariable; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RequestParam; importorg.springframework.web.bind.annotation.RestController; importjava.util.ArrayList; importjava.util.List; importjava.util.Map; /** *Createdbywuhaochaoon2017/7/21. */ /** *交易 */ @RequestMapping("/transcation") @RestController publicclassTranscationController{ @Autowired privateTranscationMappertranscationMapper; /** *获取全部交易信息 * *@return *@throwsThrowable */ @RequestMapping("/getTransInfo") publicObjectgetTranscationInfo()throwsThrowable{ List<TranscationBean>list=transcationMapper.getTranscation(); returnlist; } /** *分页获取交易信息 * *@parampagesize *@return *@throwsThrowable */ @RequestMapping("/getTransInfo/{pagesize}") publicObjectgetTranscationInfoByPage(@PathVariable("pagesize")Integerpagesize)throwsThrowable{ PageHelper.startPage(1,pagesize); List<TranscationBean>list=transcationMapper.getTranscation(); returnnewPageInfo(list); } } 定时任务 Spring Boot定时任务相对Spring quartz来说更简单。 定义一个定时任务: [html] view plain copy packagecom.example.Scheduled; /** *Createdbywuhaochaoon2017/7/21. */ importcom.example.mapper.BlockMapper; importcom.example.mapper.TranscationMapper; importcom.example.theadPoolConfig.AsyncTranscationTask; importcom.example.unitl.Until; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; importorg.springframework.transaction.annotation.Transactional; /** *定时任务,每五秒探测一次区块链中的是否存在最新交易信息 */ @Component publicclassMyScheduled{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(MyScheduled.class); @Autowired privateAsyncTranscationTaskasyncTranscationTask; @Autowired privateBlockMapperblockMapper; /*每天每5秒执行一次*/ @Scheduled(cron="0/5****?") @Transactional publicvoidexecuteTask2(){ //获取最新区块编号 try{ intblockNumberNew=Integer.parseInt( Until.encodeHexTodecimal(Until.JSONRPCClient(newObject[]{}, "eth_blockNumber").toString())); //查询数据库中存储的最新区块数据 intblockNumberDataSource=blockMapper.getBlockNum(); for(inti=blockNumberDataSource+1;i<=blockNumberNew;i++){ asyncTranscationTask.insertTransTask(i); } }catch(Throwablethrowable){ throwable.printStackTrace(); } } } @Scheduled注解定义了定时任务 启动程序中需要加上@EnableScheduling注解启动定时任务探测。 多线程 Spring Boot有自己默认的线程池,这里我们自定义一个自己的线程池。 配置线程池: [html] view plain copy packagecom.example.theadPoolConfig; /** *Createdbywuhaochaoon2017/7/25. */ importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.scheduling.annotation.EnableAsync; importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; importjava.util.concurrent.Executor; importjava.util.concurrent.ThreadPoolExecutor; /** *创建自定义线程池 */ @Configuration @EnableAsync publicclassTaskExecutePool{ @Bean publicExecutormyTaskAsyncPool(){ ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(50); executor.setQueueCapacity(1000); executor.setKeepAliveSeconds(300); //rejection-policy:当pool已经达到maxsize的时候,如何处理新任务 //CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行 executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); returnexecutor; } } @EnableAsync注解并发。 使用自定义线程池: [html] view plain copy packagecom.example.theadPoolConfig; importcom.example.entity.BlockInfoBean; importcom.example.entity.TranscationBean; importcom.example.mapper.BlockMapper; importcom.example.mapper.TranscationMapper; importcom.example.unitl.Until; importnet.sf.json.JSONArray; importnet.sf.json.JSONObject; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.scheduling.annotation.Async; importorg.springframework.stereotype.Component; importjava.util.ArrayList; importjava.util.List; /** *Createdbywuhaochaoon2017/7/25. */ @Component publicclassAsyncTranscationTask{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(AsyncTranscationTask.class); @Autowired privateTranscationMappertranscationMapper; @Autowired privateBlockMapperblockMapper; //myTaskAsynPool即配置线程池的方法名,此处如果不写自定义线程池的方法名,会使用默认的线程池 @Async("myTaskAsyncPool") publicvoidinsertTransTask(inti)throwsInterruptedException{ logger.info("TranscationTask"+i+"started."); //开始导入交易信息 Stringmethod_BlockByNumber="eth_getBlockByNumber"; JSONObjectobjects=null; List<TranscationBean>list=null; JSONObjecttranstionObject=null; TranscationBeantranscation=null; try{ objects=JSONObject.fromObject(Until.JSONRPCClient(newObject[]{i,true},method_BlockByNumber)); }catch(Throwablethrowable){ throwable.printStackTrace(); } //插入区块信息 BlockInfoBeanblockInfoBean=newBlockInfoBean(objects); blockMapper.insertBlockInfo(blockInfoBean); if(JSONArray .fromObject(objects.get("transactions")).size()>0){ list=newArrayList<TranscationBean>(); for(java.util.Iteratortor=JSONArray .fromObject(objects.get("transactions")) .iterator();tor.hasNext();){ transtionObject=(JSONObject)tor.next(); transcation=newTranscationBean(transtionObject); transcation.setTimestamp(Until.formatTimeMillis(objects.get("timestamp").toString())); list.add(transcation); } //批量插入 transcationMapper.insertTranscationList(list); } } } 启动程序中需要加上@ EnableAsync注解启动自定义线程池。 部署 Spring Boot默认打包为jar,按照官方文档操作即可,这里我们打包为war包,可以与前台静态页面交互的web应用。 POM文配置: [html] view plain copy <!--加入静态文件和jsp--> <!--对jsp的支持--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <!--打包时需要添加以下依赖--> <!--<scope>provided</scope>--> </dependency> <!--配置servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> [html] view plain copy <!--这里指定打包的时候不再需要tomcat相关的包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <!--打包时需要添加以下依赖--> <!--<scope>provided</scope>--> </dependency> [html] view plain copy <!--手工设置resource--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*</include> </includes> </resource> <resource> <directory>src/main/webapp</directory> <includes> <include>**/*</include> </includes> </resource> </resources> [html] view plain copy <!--打包跳过测试--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> <!--maven打包的时候告诉maven不需要web.xml,否刚会报找不到web.xml错误--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <!--将外部依赖打入war包的lib目录下--> <webResources> <resource> <directory>src/lib</directory> <targetPath>WEB-INF/lib/</targetPath> <includes> <include>**/*.jar</include> </includes> </resource> </webResources> </configuration> </plugin> 添加本地jar: [html] view plain copy <!--添加外部依赖--> <dependency> <groupId>Ice</groupId> <artifactId>Ice</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${basedir}/src/lib/jsonrpc4j-0.27.jar</systemPath> </dependency>