为了节约开发时间先整一个小架构,网站初期访问不会太大,这套架构可以使用一段时间,废话不多说,开搞。
在idea中创建一个maven工程作为父工程,给它的pom.xml配置一下
<?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.java.lzw</groupId> <artifactId>lzwmall</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>generator</module> <module>poral</module> <module>common</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--MyBatis分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.10</version> </dependency> <!--集成druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> </dependencies> </project>
创建一个子common工程,还是maven工程,修改pom.xml
<?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.java.lzw</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>common</name> <description>common project for lzwmall</description> <dependencies> <!--Swagger-UI API文档生产工具--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency> <!--分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.8</version> </dependency> <!--Spring Data家族有多个模块,所有的模块都基于Spring Data Commoms模块进行扩展, 例如Spring Data JPA是针对JPA做扩展的一个子模块;Spring Data Mongo是针对MongoDB的子模块,但是共同的接口都是Spring Data。 可以说Spring Data Commons是其所有子模块的抽象,定义了一系列的操作标准及接口。--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>2.1.5.RELEASE</version> </dependency> <!--Hutool Java工具包--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.5.7</version> </dependency> </dependencies> </project>
common的项目结构
CommonPage
package com.common.api; import com.github.pagehelper.PageInfo; import org.springframework.data.domain.Page; import java.util.List; /** * 分页数据封装类 * Created by macro on 2019/4/19. */ public class CommonPage<T> { private Integer pageNum; private Integer pageSize; private Integer totalPage; private Long total; private List<T> list; /** * 将PageHelper分页后的list转为分页信息 */ public static <T> CommonPage<T> restPage(List<T> list) { CommonPage<T> result = new CommonPage<T>(); PageInfo<T> pageInfo = new PageInfo<T>(list); result.setTotalPage(pageInfo.getPages()); result.setPageNum(pageInfo.getPageNum()); result.setPageSize(pageInfo.getPageSize()); result.setTotal(pageInfo.getTotal()); result.setList(pageInfo.getList()); return result; } /** * 将SpringData分页后的list转为分页信息 */ public static <T> CommonPage<T> restPage(Page<T> pageInfo) { CommonPage<T> result = new CommonPage<T>(); result.setTotalPage(pageInfo.getTotalPages()); result.setPageNum(pageInfo.getNumber()); result.setPageSize(pageInfo.getSize()); result.setTotal(pageInfo.getTotalElements()); result.setList(pageInfo.getContent()); return result; } public Integer getPageNum() { return pageNum; } public void setPageNum(Integer pageNum) { this.pageNum = pageNum; } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public Integer getTotalPage() { return totalPage; } public void setTotalPage(Integer totalPage) { this.totalPage = totalPage; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } public Long getTotal() { return total; } public void setTotal(Long total) { this.total = total; } }
CommonResult
package com.common.api; /** * 通用返回对象 * Created by macro on 2019/4/19. */ public class CommonResult<T> { private long code; private String message; private T data; protected CommonResult() { } protected CommonResult(long code, String message, T data) { this.code = code; this.message = message; this.data = data; } /** * 成功返回结果 * * @param data 获取的数据 */ public static <T> CommonResult<T> success(T data) { return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data); } /** * 成功返回结果 * * @param data 获取的数据 * @param message 提示信息 */ public static <T> CommonResult<T> success(T data, String message) { return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data); } /** * 失败返回结果 * @param errorCode 错误码 */ public static <T> CommonResult<T> failed(IErrorCode errorCode) { return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null); } /** * 失败返回结果 * @param message 提示信息 */ public static <T> CommonResult<T> failed(String message) { return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null); } /** * 失败返回结果 */ public static <T> CommonResult<T> failed() { return failed(ResultCode.FAILED); } /** * 参数验证失败返回结果 */ public static <T> CommonResult<T> validateFailed() { return failed(ResultCode.VALIDATE_FAILED); } /** * 参数验证失败返回结果 * @param message 提示信息 */ public static <T> CommonResult<T> validateFailed(String message) { return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null); } /** * 未登录返回结果 */ public static <T> CommonResult<T> unauthorized(T data) { return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data); } /** * 未授权返回结果 */ public static <T> CommonResult<T> forbidden(T data) { return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data); } public long getCode() { return code; } public void setCode(long code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
IErrorCode
package com.common.api; /** * 封装API的错误码 * Created by macro on 2019/4/19. */ public interface IErrorCode { long getCode(); String getMessage(); }
ResultCode
package com.common.api; /** * 枚举了一些常用API操作码 * Created by macro on 2019/4/19. */ public enum ResultCode implements IErrorCode { SUCCESS(200, "操作成功"), FAILED(500, "操作失败"), VALIDATE_FAILED(404, "参数检验失败"), UNAUTHORIZED(401, "暂未登录或token已经过期"), FORBIDDEN(403, "没有相关权限"); private long code; private String message; private ResultCode(long code, String message) { this.code = code; this.message = message; } public long getCode() { return code; } public String getMessage() { return message; } }
创建子工程,maven工程,作为数据层项目
<?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.java.lzw</groupId> <artifactId>generator</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>generator</name> <description>generator project for lzwmall</description> <dependencies> <dependency> <groupId>com.java.lzw</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- MyBatis 生成器 --> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.3</version> </dependency> <!-- MyBatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!--Mysql数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> </dependencies> </project>
generator的项目架构
CommentGenerator
package com.generator; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.dom.java.CompilationUnit; import org.mybatis.generator.api.dom.java.Field; import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; import org.mybatis.generator.internal.DefaultCommentGenerator; import org.mybatis.generator.internal.util.StringUtility; import java.util.Properties; /** * 自定义注释生成器 * Created by macro on 2018/4/26. */ public class CommentGenerator extends DefaultCommentGenerator { private boolean addRemarkComments = false; private static final String EXAMPLE_SUFFIX="Example"; private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty"; /** * 设置用户配置的参数 */ @Override public void addConfigurationProperties(Properties properties) { super.addConfigurationProperties(properties); this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments")); } /** * 给字段添加注释 */ @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { String remarks = introspectedColumn.getRemarks(); //根据参数和备注信息判断是否添加备注信息 if(addRemarkComments&&StringUtility.stringHasValue(remarks)){ // addFieldJavaDoc(field, remarks); //数据库中特殊字符需要转义 if(remarks.contains("\"")){ remarks = remarks.replace("\"","'"); } //给model的字段添加swagger注解 field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\")"); } } /** * 给model的字段添加注释 */ private void addFieldJavaDoc(Field field, String remarks) { //文档注释开始 field.addJavaDocLine("/**"); //获取数据库字段的备注信息 String[] remarkLines = remarks.split(System.getProperty("line.separator")); for(String remarkLine:remarkLines){ field.addJavaDocLine(" * "+remarkLine); } addJavadocTag(field, false); field.addJavaDocLine(" */"); } @Override public void addJavaFileComment(CompilationUnit compilationUnit) { super.addJavaFileComment(compilationUnit); //只在model中添加swagger注解类的导入 if(!compilationUnit.isJavaInterface()&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){ compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME)); } } }
Generator
package com.generator; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * 用于生产MBG的代码 * Created by macro on 2018/4/26. */ public class Generator { public static void main(String[] args) throws Exception { //MBG 执行过程中的警告信息 List<String> warnings = new ArrayList<String>(); //当生成的代码重复时,覆盖原代码 boolean overwrite = true; //读取我们的 MBG 配置文件 InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(is); is.close(); DefaultShellCallback callback = new DefaultShellCallback(overwrite); //创建 MBG MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); //执行生成代码 myBatisGenerator.generate(null); //输出警告信息 for (String warning : warnings) { System.out.println(warning); } } }
generator.properties
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.connectionURL=jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai jdbc.userId=root jdbc.password=123456
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="generator.properties"/> <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat"> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <property name="javaFileEncoding" value="UTF-8"/> <!-- 为模型生成序列化方法--> <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> <!-- 为生成的Java模型创建一个toString方法 --> <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/> <commentGenerator type="com.generator.CommentGenerator"> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true"/> <property name="suppressDate" value="true"/> <property name="addRemarkComments" value="true"/> </commentGenerator> <jdbcConnection driverClass="${jdbc.driverClass}" connectionURL="${jdbc.connectionURL}" userId="${jdbc.userId}" password="${jdbc.password}"> <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题--> <property name="nullCatalogMeansCurrent" value="true" /> </jdbcConnection> <javaModelGenerator targetPackage="com.generator.model" targetProject="generator\src\main\java"/> <sqlMapGenerator targetPackage="mapper" targetProject="generator\src\main\resources"/> <javaClientGenerator type="XMLMAPPER" targetPackage="com.generator.mapper" targetProject="generator\src\main\java"/> <!--生成全部表tableName设为%--> <table tableName="%"> <generatedKey column="id" sqlStatement="MySql" identity="true"/> </table> </context> </generatorConfiguration>
如果你不想连接我的数据库,可以将generator.properties中的数据连接改为你自己的,到时运行Generator中的main方法,生成你自己的数据文件
创建一个Springboot子工程,作为门户,网站前台给用户看的,修改pom.xml
<?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.java.lzw</groupId> <artifactId>poral</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>poral</name> <description>poral project for lzwmall</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties> <parent> <groupId>com.java.lzw</groupId> <artifactId>lzwmall</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../</relativePath> </parent> <dependencies> <!--依赖数据层--> <dependency> <groupId>com.java.lzw</groupId> <artifactId>generator</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--集成logstash,logstash就是一根具备实时数据传输能力的管道,负责将数据信息从管道的输入端传输到管道的输出端; 与此同时这根管道还可以让你根据自己的需求在中间加上滤网,Logstash提供里很多功能强大的滤网以满足你的各种应用场景。 Logstash常用于日志关系系统中做日志采集设备--> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>4.8</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
poral的项目架构
config中的MyBatisConfig
package com.java.lzw.poral.config; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** * MyBatis配置类 * Created by macro on 2019/4/8. */ @Configuration @EnableTransactionManagement @MapperScan({"com.generator.mapper","com.java.lzw.poral.dao"})//第一个参数对应generator项目的mapper接口,第二个参数对应本项目自定义的dao(mapper)层接口 public class MyBatisConfig { }
config中的SwaggerConfig
package com.java.lzw.poral.config; import io.swagger.annotations.ApiOperation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.java.lzw.poral.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("商城前台系统") .description("商城前台系统") .contact("lzw") .version("1.0") .build(); } }
controller中的DemoController
package com.java.lzw.poral.controller; import com.generator.model.OmsOrder; import com.java.lzw.poral.service.OmsOrderService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Api(description = "测试接口") @Controller @RequestMapping("/demoController") public class DemoController { @Autowired private OmsOrderService omsOrderService; @ApiOperation("测试") @RequestMapping(value = "/mail", method = RequestMethod.GET) @ResponseBody public List<OmsOrder> sendMail() { List<OmsOrder> orderList = omsOrderService.getOrderInfo(); return orderList; } }
dao层是你自定义的mapper接口,我这边只是做一个测试先没有写
service层的OmsOrderService
package com.java.lzw.poral.service; import com.generator.model.OmsOrder; import java.util.List; public interface OmsOrderService { List<OmsOrder> getOrderInfo(); }
service.impl层的
package com.java.lzw.poral.service.impl; import com.generator.mapper.OmsOrderMapper; import com.generator.model.OmsOrder; import com.generator.model.OmsOrderExample; import com.java.lzw.poral.service.OmsOrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class OmsOrderServiceImpl implements OmsOrderService { @Autowired private OmsOrderMapper orderMapper; @Override public List<OmsOrder> getOrderInfo() { OmsOrderExample omsOrderExample = new OmsOrderExample(); OmsOrderExample.Criteria criteria = omsOrderExample.createCriteria(); return orderMapper.selectByExample(omsOrderExample); } }
启动类PoralApplication
package com.java.lzw.poral; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PoralApplication { public static void main(String[] args) { SpringApplication.run(PoralApplication.class, args); } }
resoures下的application.properties没有写
resoures下的application.yml
spring: profiles: active: dev #默认为开发环境 mybatis: mapper-locations: - classpath*:mapper/*.xml logging: level: root: info #日志配置DEBUG,INFO,WARN,ERROR com.macro.mall: debug # file: demo_log.log #配置日志生成路径 # path: /var/logs #配置日志文件名称
resoures下的application-dev.yml
spring: datasource: url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 123456 druid: initial-size: 5 #连接池初始化大小 min-idle: 10 #最小空闲连接数 max-active: 20 #最大连接数 web-stat-filter: exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据 stat-view-servlet: #访问监控网页的登录用户名和密码 login-username: druid login-password: druid
新加resoures下的logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <include resource="org/springframework/boot/logging/logback/console-appender.xml"/> <!--应用名称--> <property name="APP_NAME" value="mall-admin"/> <!--日志文件保存路径--> <property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/> <contextName>${APP_NAME}</contextName> <!--每天记录日志到文件appender--> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> </appender> <!--输出到logstash的appender--> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>localhost:4560</destination> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/> </appender> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> <appender-ref ref="LOGSTASH"/> </root> </configuration>
这个时候后端架构基本搭好了,小架构:springboot+mybatis+MyBatisGenerator+Swagger-UI+PageHelper
现在有二种方式,一个是在poral项目中写页面,一种是新建一个项目前后端分离
我现在一个开发就不分离了,直接写到poral项目中
poral的架构
把你的静态资源搞进 static包里
把你的页面搞到templates里面去
修改一下application.properties文件
server.port=8084 #这里使用thymeleaf模板引擎代替jsp页面 spring.thymeleaf.mode=LEGACYHTML5 spring.thymeleaf.cache=false
使用thymeleaf需要导入依赖到poral项目中
<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>2.1.4</version> </dependency>
页面也要加头文件
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
如果不会使用thymeleaf我之前的博客中给上链接https://blog.csdn.net/java_wxid/article/details/86498332
当然如果你是新手用jsp写也没有事。
如果是前后端分离:启动后端项目在浏览器中输入:http://localhost:8084/swagger-ui.html#/
可以查看你的接口文档
不过你需要部署你的接口到服务器,前端人员才可进行开发。
剩下的就属于你的开发时间了,网站做成什么样就看你的开发水平了,这里我就不写了。
当然我还知道有很多东西没有配置,像什么alipay,短信验证码,权限,缓存,信息队列之类的,但初期第一版也就先这样吧。
这里给上简单的项目链接可以下载:
链接:https://pan.baidu.com/s/1coEfS73tsP9wmSJ-ewb45g
提取码:fy5n
如果写好你的项目运行不报错之后就该部署项目到网上去,让用户可以通过域名访问你的网站了,部署也有二种情况,一种用自己的机器部署,一种用云服务器,而这二种可以分为普通部署和使用docker部署,这里我给上之前有部署过的项目部署流程的博客地址https://blog.csdn.net/java_wxid/article/details/89785556。
这种情况是用我的笔记本部署,用云数据库连接。当然如果你习惯了linux系统部署,而且像快速部署到云服务器上建议你购买所需的环境镜像并重装该镜像即可,这样可以少了很多配置。
重装系统操作文档链接:https://cloud.tencent.com/document/product/213/4933
需要有搭建tomcat的集成环境即可,这边为您推荐与之相关的环境供您参考。
Java运行环境(nginx+mysql+tomcat) :https://market.cloud.tencent.com/products/6483
现在是激动人心的时刻了,引入广告联盟,赚钱的时候了。
麒麟广告联盟(www.70e.com),支持点击和弹窗。一千点击100元。一千弹窗50元。周付,50元起付,支持网银,最好的是支持支付宝。比较好的公司运营联盟除开百度跟谷歌外,再就是酷奇广告联盟,他们那边不扣量,不扣税,不扣手续费。
这里就介绍二家,具体流程我也不好写,毕竟每家的不同,要求也不同,弄好这些杂七杂八的东西,把你的广告引入的项目中就ok了。到时直接根据访问量拿钱,所以你需要对你的网站弄一个吸引人的点,这里方式多种,我就不介绍了。
如果有疑问可以在评论下方留言,一般我都在,也可以访问我的个人网站:www.javawxid.com.cn找到我的微信私聊我
这篇我尽力了,写了这么多,点个关注呗,或者看看我的主页,相信你会关注我的。