A01 互联网O2O平台开发.txt
UP 返回
该项目为互联网O2O平台开发,视频地址:D:\实战JAVA项目20套\Java互联网项目教学\互联网O2O平台开发
经过去重路径变为:H:\视频教程\53套JAVA技术提升及架构精华课\46.第四十六套 ssm到spring boot开发校园商铺平台(2021/8/14)
项目地址:D:\ProjectCodes\eclipse2019\o2o
A 项目初步搭建(视频01-04章)
1 eclipse创建maven项目
首先需要在eclipse中配好jdk,maven和tomcat。在server窗口下右键新增server,然后选择对应的tomcat版本及目录即可
File → MavenProject → 修改一下工作空间(这里用的D:\ProjectCodes) → maven-archetype-webapp→ 输入两个id(com.imooc o2o) → 完成
项目此时是报错的,需要添加一个tomcat下的一个jar:项目右键属性 → java build path → libraries → add library → server runtime → 选择对应的tomcat → OK,不报错了
此时项目还有一个警告,jre版本不匹配:去jar网页搜索maven-compile-plugin,复制dependency 放到pom.xml中(pom里添加plugins):
<build>
<finalName>o2o</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId> 这里去掉dependency标签,因为放在了插件里,与pom上面的依赖有区别
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source> configuration指明这个插件和jdk1.8联系在一起的
<target>1.8</target>
<encoding>UTF8</encoding> 指明编码
</configuration>
</plugin>
</plugins>
</build>
添加后maven update一下项目,就不报错了,同时会多出两个source目录
手动添加source folder,src/test/resources,,右键项目属性,在java build path的source下,会发现每一个source folder都有对应的output folder,新加的只有一个default,他应该是target/test-classes
记得先双击修改一下下面的contains test sources,将其从no改为yes,,然后双击output folder修改值保存(这个文件夹只是为了符合maven的规范而创建的)
右键项目属性,选择project facets,设置Dynamic Web Module(版本越高解析js和页面的能力越强,但是高版本需要的jdk要求也更高),这里可以选择4.0
实际测试发现选择了高版本以后无法再回到低版本,视频上演示的则是无论如何都无法切换(演示的eclipse有bug),此时可以进入项目路径的目录下:D:\ProjectCodes\eclipse2019\o2o\o2o\.settings
里面有个文件org.eclipse.wst.common.project.facet.core.xml,通过手动修改<installed facet="jst.web" version="4.0"/>的value也可以实现修改,修改后refresh一下项目
修改以后web.xml上的规范也需要修改:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<display-name>Archetype Created Web Application</display-name>
</web-app>
项目的webapp下有一个index.jsp,就是默认的首页。在server面板中选中对应的tomcat,右键选择Add and Remove,将当前项目添加进去,clean工程,再右键start服务器启
此时即可通过 http://localhost:8080/o2o/index.jsp 访问默认的页面index.jsp
http://localhost:8080/o2o 也可以访问到该页面。可以在web.xml中设置默认访问的页面,如果不设置就会默认去访问根路径下的index.jsp;如果设置了却找不到对应页面,就会报404错误
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<!-- ▶▶▶ 设置默认的访问页面,从上往下依次找 -->
<welcome-file>aa.jsp</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2 项目完善
在src/mian/resources下右键创建两个source文件夹,命名为src/mian/resources/spring和src/mian/resources/mapper
在下面的页面文件夹中,src/main/webapp下创建文件夹resources,用来存放静态文件(js, css, 图片等)。WEB-INF中的页面是无法从浏览器直接访问到的
准备好数据库,并创建所有的实体类,接下来引入项目需要的jar,初步的pom文件内容如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dm</groupId>
<artifactId>o2o</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>o2o Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.3.7.RELEASE</spring.version> 补上${spring.version}定义的值,用于和下面的spring版本对应
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope> test表示只希望出现在测试环境中,这个项不填则默认为compile
</dependency>
<!-- 日志 -->
<!-- 实现slf4j接口并整合 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- Spring -->
<!-- 1)包含Spring框架基本的核心工具类。Spring其他组件都要使用到这个包里的类,是其他组件的基本核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 2)这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行IOC/DI操作相关的所有类。如果应用只需要基本的IOC/DI支持,引入spring-core及spring-beans.jar文件就可以了 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 3)这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,instrumentation组件以及校验Validation方面的相关类 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 4)这个jar文件包含Spring对.数据访问进行封装的所有类 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 5)为JDBC、Hibernate、JDO、JPA等提供一致的声明式和编程式事务管理 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 6)Spring web包含web应用开发时用到的核心类,包括自动载入WebApplicationContext特性的类,文件上传的类等-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 7)SpringMVC的核心,包括DispatcherServlet等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 8)Spring test对JUNIT等测试框架的简单封装。这个依赖使用test,只希望在测试环境出现 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- Spring web,提供servlet服务-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- json解析 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
<!-- Map工具类 对标准java Collection的扩展 spring-core.jar需commons-collections.jar -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<!-- DAO: MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId
<version>5.1.37</version>
<!-- <scope>runtime</scope> -->
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
<build>
<finalName>o2o</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
其他配置文件参项目代码(视频2-6)
2.1 在resources目录下创建jdbc.properties,内容为
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123654
2.2 在resources目录下创建mybatis-config.xml,用于配置mybatis,内容为
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置全局属性 -->
<settings>
<!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 使用列标签替换列别名 默认:true -->
<setting name="useColumnLabel" value="true" />
<!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
</configuration>
2.3 在resources下创建spring文件夹,spring下创建spring-dao.xml文件,内容为
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> 这一大坨表示命名空间等配置,固定的写法
<!-- 配置整合mybatis过程 -->
<!-- 1.配置数据库相关参数properties的属性:${url} -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 2.数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置连接池属性 -->
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="30" />
<property name="minPoolSize" value="10" />
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false" />
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000" />
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2" />
</bean>
<!-- 3.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 扫描entity包 使用别名 -->
<property name="typeAliasesPackage" value="com.imooc.myo2o.entity" />
<!-- 扫描sql配置文件:mapper需要的xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml" />
</bean>
<!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.imooc.myo2o.dao" />
</bean>
</beans>
2.4 在spring下创建spring-service.xml文件,内容为
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 扫描service包下所有使用注解的类型 -->
<context:component-scan base-package="com.imooc.myo2o.service" />
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置基于注解的声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
2.5 在spring下创建spring-web.xml文件,内容为
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 配置SpringMVC -->
<!-- 1.开启SpringMVC注解模式 -->
<mvc:annotation-driven />
<!-- 2.静态资源默认servlet配置
(1)加入对静态资源的处理:js,gif,png
(2)允许使用"/"做整体映射 -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:default-servlet-handler />
<!-- 3.定义视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 只要文件放在WEB-INF下,程序外部便不可以访问这里的文件,内部可以,所以使用这个文件夹可以保证安全,通过springDispacherServlet来进行转向,controller来分发到WEB-INF下的页面即可 -->
<property name="prefix" value="/WEB-INF/html/"></property>
<property name="suffix" value=".html"></property>
</bean>
<!-- 4.扫描web相关的bean -->
<context:component-scan base-package="com.imooc.myo2o.web" />
</beans>
2.6 在web.xml中整合spring的相关配置
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<!-- 设置默认的访问页面,从上往下依次找 -->
<welcome-file>aa.jsp</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 这里就是将spring的配置文件组合到一起了 -->
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<!-- 默认匹配所有的请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
实际代码: (对应视频2-7)
3.1 在包com.imooc.myo2o.entity下创建Area类,代码如下
public class Area {
private Long areaId;
private String areaName;
private String areaDesc;
private Integer priority;
private Date createTime;
private Date lastEditTime;
//省略get set
}
3.2 在包com.imooc.myo2o.dao下创建AreaDao类,代码如下
public interface AreaDao {
List<Area> queryArea();
}
3.3 在resources下的mapper创建AreaDao.xml,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.myo2o.dao.AreaDao">
<select id="queryArea" resultType="com.imooc.myo2o.entity.Area">
SELECT
area_id,
area_name,
area_desc,
priority,
create_time,
last_edit_time
FROM
tb_area
ORDER BY
priority DESC
</select>
</mapper>
3.4 在src/test/java下的com.imooc.myo2o下创建测试类BaseTest,内容如下
/**
* 配置spring和junit整合,junit启动时加载springIOC容器 spring-test,junit
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:spring/spring-dao.xml" }) // 告诉junit spring配置文件的位置
public class BaseTest {
}
3.5 在com.imooc.myo2o.dao下创建测试类ATest,内容如下
public class AreaDaoTest extends BaseTest {
@Autowired
private AreaDao areaDao;
@Test
public void testBQueryArea() throws Exception {
List<Area> areaList = areaDao.queryArea();
assertEquals(4, areaList.size());
}
}
接下来Junit运行testBQueryArea,即可成功!!!!
补充其他模块: (对应视频2-8)
4.1 在包com.imooc.myo2o.service下创建service,代码如下
public interface AreaService {
List<Area> getAreaList();
}
在包com.imooc.myo2o.service.Impl下创建实现类,代码如下
@Service
public class AreaServiceImpl implements AreaService {
@Autowired
private AreaDao areaDao;
@Override
public List<Area> getAreaList() {
return areaDao.queryArea();
}
}
4.2 在测试包com.imooc.myo2o.service下创建AreaServiceTest,代码如下
public class AreaServiceTest extends BaseTest {
@Autowired
private AreaService areaService;
@Test
public void testGetAreaList() {
List<Area> areaList = areaService.getAreaList();
assertEquals("东苑", areaList.get(0).getAreaName());
}
}
此时需要在BaseTest的配置文件属性中加上classpath:spring/spring-service.xml。运行测试方法,即可成功!!!!
4.3 创建包com.imooc.myo2o.web.superadmin,包下创建AreaController,代码如下 (对应视频2-9)
@Controller
@RequestMapping("/superadmin")
public class AreaController {
@Autowired
private AreaService areaService;
@RequestMapping(value = "/listarea", method = RequestMethod.GET)
@ResponseBody
private Map<String, Object> listArea() {
Map<String, Object> modelMap = new HashMap<String, Object>();
List<Area> list = new ArrayList<Area>();
try {
list = areaService.getAreaList();
modelMap.put("rows", list);
modelMap.put("total", list.size());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
modelMap.put("success", false);
modelMap.put("errMsg", e.toString());
}
return modelMap;
}
}
启动tomcat,可以直接在页面访问http://localhost:8080/o2o/superadmin/listarea得到信息,或者通过postman测试也可以!!!!
3 logback (视频3-2)
3.1 logback对配置的加载顺序
java程序在运行时有一个参数 Dlogback.configurationFile参数,如果指定了的话,那么就会首先去找这个参数的地址来加载配置
java -Dlogback.configurationFile=xxxxxx/xxx.xml
如果没有配置这个属性,那么就会去加载classpath里的logback.groovy文件
如果没有这个文件,还会加载同级目录下的logback-test.xml文件
如果还没有,就会加载同目录下logback.xml文件
如果还没有,jdk在1.6以上的话,会调用ServiceLoader去查找一个com.qos.logback.classic.spi.Configurator接口的第一个实现类,在类中硬编码上相关的配置
如果还没有,就会用默认的实现类ch.qos.logback.classic.BasicConfigurator,这个日志就只会输出到控制台当中
3.2 配置文件
在resources下创建logback.xml,内容为:
<?xml version="1.0" encoding="utf-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- scan属性设置为true时表示当配置文件发生改变时会自动重新加载,默认即为true -->
<!-- scanPeriod表示扫描的时间间隔,默认单位为ms。这里指定单位为秒,设置为一分钟扫描一次 -->
<!-- debug为true时表示将会打印出logback内部的日志信息,一般是没必要的 -->
<!-- 定义参数常量 -->
<!-- TRACE<DEBUG<INFO<WARN<ERROR 程序中使用logger.trace("msg")/debug("msg")/...,设置后面的级别前面的语句将无法打印出来 -->
<property name="log.level" value="debug"/>
<!-- 日志保留多长时间 -->
<property name="log.maxHistory" value="30"/>
<!-- 日志存储的根路径,这里表示tomcat实例的根目录下的logs/webapps -->
<property name="log.filePath" value="${catalina.base}/logs/webapps"/>
<!-- 日志格式 这里的格式为:时间 线程 级别(从左往右输出5位) 输出日志的类 日志内容 换行-->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
<!-- appender定义日志的输出介质 即日志输出的地方-->
<!-- 控制台日志 -->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志信息的格式 encoder既将日志转换成字符串,又将其写入文件-->
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- DEBUG日志 这里面的类表示会根据文件大小滚动生成新的文件-->
<appender name="debugAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 文件路径 -->
<file>${log.filePath}/debug.log</file>
<!-- 滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 指定日志压缩文件名称格式 logback会自动将日志压缩-->
<fileNamePattern>${log.filePath}/debug/debug.%d{yyyy-MM-dd}.log.gz
</fileNamePattern>
<!-- 日志保留的最大个数 此处表示保留30个,因为是按天生成,相当于保留30天 -->
<maxHistory>${log.maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<!-- 日志过滤器,此处表示只记录DEBUG日志,符合的就accept,不符合的就拒绝deny -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- INFO日志 配置同上,debug换成info即可-->
<appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.filePath}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.filePath}/info/info.%d{yyyy-MM-dd}.log.gz
</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- ERROR日志 配置同上,debug换成error即可-->
<appender namae="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.filePath}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.filePath}/error/error.%d{yyyy-MM-dd}.log.gz
</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- logger存放日志对象,name属性告诉appender需要关注哪些包的信息,level表示仅记录其以上的日志信息 -->
<!-- additivity设为true时会将root中的appender也放入logger中,这样logger中的日志也会输出到控制台里 -->
<!-- 一个类的logger只能指定一个地方,要么是logger要么是root,这里放在了logger里,但是root也包含过来了,所以也会输出到root中设置的控制台里 -->
<logger name="com.imooc.myo2o" level="${log.level}" additivity="true">
▶imooc,,之前写成了immoc,一直不符合设置,,可恶!!!
<!-- logger需要和appender绑定 -->
<appender-ref ref="debugAppender"/>
<appender-ref ref="infoAppender"/>
<appender-ref ref="errorAppender"/>
</logger>
<!-- 根日志,只有level属性,就是特殊的logger。如果logger不指定level那么就会继承root的level -->
<root level="info">
<appender-ref ref="consoleAppender"/>
</root>
</configuration>
3.3 运行 (对应视频3-3)
在AreaController中添加日志:
public class AreaController {
Logger logger = (Logger) LoggerFactory.getLogger(AreaController.class); //演示的代码中并没有做强转,这里不做会编译报错,不知为啥
@Autowired
private AreaService areaService;
@RequestMapping(value = "/listarea", method = RequestMethod.GET)
@ResponseBody
private Map<String, Object> listArea() {
logger.info("===start==="); //▶
long startTime = System.currentTimeMillis();
Map<String, Object> modelMap = new HashMap<String, Object>();
List<Area> list = new ArrayList<Area>();
try {
list = areaService.getAreaList();
modelMap.put("rows", list);
modelMap.put("total", list.size());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
modelMap.put("success", false);
modelMap.put("errMsg", e.toString());
}
logger.error("test error!"); //▶
long endTime = System.currentTimeMillis();
logger.debug("costTime:[{}ms]", endTime - startTime); //▶
logger.info("===end==="); //▶
return modelMap;
}
}
启动tomcat,可以看到控制台会打印tomcat的文件夹,即配置中的${catalina.base}参数值:
CATALINA_BASE: D:\ProjectCodes\eclipse2019\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
复制进入文件夹,会发现生成了info debug error的日志文件。去浏览器访问http://localhost:8080/o2o/superadmin/listarea,控制台会输出日志:
2021-06-04 00:53:36.309 [http-nio-8080-exec-3] INFO com.imooc.myo2o.web.superadmin.AreaController - ===start===
2021-06-04 00:53:37.128 [http-nio-8080-exec-3] ERROR com.imooc.myo2o.web.superadmin.AreaController - test error!
2021-06-04 00:53:37.128 [http-nio-8080-exec-3] DEBUG com.imooc.myo2o.web.superadmin.AreaController - costTime:[810ms]
2021-06-04 00:53:37.132 [http-nio-8080-exec-3] INFO com.imooc.myo2o.web.superadmin.AreaController - ===end===
同时对应文件也会记录log。。。过一天的话日志会自动打包进文件夹,验证成功
4 补充文件上传类,Shop的service类和对应测试类 (对应视频4-1~4-5) ▶里面有给图片加水印的测试方法,参ImageUtil类
<!-- 图片处理 -->
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
实例网址:https://github.com/coobird/thumbnailator/wiki/Examples
数据库事务必须抛出RuntimeException或其子类的异常才能回滚
这里面视频信息有缺失,但是后面的视频有说明。示例代码中使用的是CommonsMultipartFile,但是这样Junit启动就会报spring的错,故后面改成了File类,方便测试。这样在写controller时就得做转换,CommonsMultipartFile中是可以拿到文件流的
5 补充controller中插入店铺的代码,这里涉及到jackson-databind的使用,部分代码如下:
//▶用ObjectMapper将string转为对象
String shopStr = HttpServletRequestUtil.getString(request, "shopStr");
ObjectMapper mapper = new ObjectMapper();
Shop shop = null;
try {
shop = mapper.readValue(shopStr, Shop.class);
} catch (Exception e) {}
//▶从servlet中获取CommonsMultipartFile文件
CommonsMultipartFile shopImg = null;
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
if (commonsMultipartResolver.isMultipart(request)) {
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
} else {}
其他详细代码见ShopManagementController的registerShop方法,包括利用CommonsMultipartFile中的流来转为File
6 使用sui mobile作为前端 (视频4-6前端设计)
视频演示的是使用淘宝的cdn来引入css和js,但是现在官网上已经没有这个连接了,所以需要自行下载压缩包,并把文件夹放入webapp下提供给html引入:
<link rel="stylesheet" href="sui/css/sm.min.css">
<link rel="stylesheet" href="sui/css/sm-extend.min.css">
<script src='//cdn.bootcss.com/jquery/3.1.1/jquery.min.js'></script>
<script src='sui/js/sm.js'></script>
<script src='sui/js/sm-extend.js'></script>
但是在后面将html页面放入WEB-INF中,通过controller访问时又下载不到了,需要在前面加上../
<link rel="stylesheet" href="../sui/css/sm.min.css">
<link rel="stylesheet" href="../sui/css/sm-extend.min.css">
<script src='//cdn.bootcss.com/jquery/3.1.1/jquery.min.js'></script>
<script src='../sui/js/sm.js'></script>
<script src='../sui/js/sm-extend.js'></script>
一般将css的引入放在html的前部分,js放在后部分,这样可以让样式先显示出来,数据后加载,比较合适
7 引入验证码和文件上传解析器完成店铺新增的代码(视频4-8 —— 4-12)
<!-- 验证码 相关参数配置见web.xml-->
<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<!-- 文件上传处理 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 文件上传解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<!-- 最大上传文件大小 1024*1024*20M-->
<property name="maxUploadSize" value="20971520"></property>
<property name="maxInMemorySize" value="20971520"></property>
</bean>
B MySQL主从库同步与读写分离
8
C 项目学习
9. 实际代码解释参:D:\ProjectCodes\eclipse2019\o2o
10. 网站的首页上的图片无法正常显示,是因为数据库中的字段使用的是相对路径,所以页面取不到(当然本项目本身就没有图片,所以实际测试需要先把文件准备好)
此时可以再后台遍历将父文件夹的路径拼上去,,但是这样做有点损失性能,所以可以使用tomcat自动给该字段拼接。
在eclipse中,添加了tomcat以后,就会自动有一个Servers的项目,点进去选中对应的tomcat,选中server.xml,拉到最下面可以看到一个Context标签
可以看到里面对path=/o2o做了处理,所以在页面上访问前加上项目名:http://localhost:8080/o2o就可以定位到这个docBase中的项目
类似的我们可以添加一个Context标签,在解析到图片路径时,自动给他转到实际的文件夹地址:
<Context docBase="D:\TestFolder\fold1\upload\frontend" path="/upload/images/item/headtitle"/> 此处为轮播图
<Context docBase="D:\TestFolder\fold1\upload\shopcategory" path="/upload/images/item/shopcategory"/> 此处为一级大类图
此配置不依赖于项目名,与项目同级。这样在其他项目中该映射其实也是有效的
11.阿里云部署Java网站和微信开发调试 视频文档地址:https://www.imooc.com/article/20583
11.1 阿里云服务器部署
选择云服务器ECS,系统为linux centOS最新的即可,SecureCRT远程连接公有地址登录,密码可以从平台上查到,端口默认。winscp的登录相同。
远程登录默认进入root文件夹,cd ../可以返回上一次层。这里直接在root文件夹下将下载好的文件用winscp拖进来。文件和路径为(实际文件名按下载页面显示为准):
JDK1.8 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 选择下载jdk-8u144-linux-x64.rpm
tomcat8 http://tomcat.apache.org/download-80.cgi#8.0.46 选择下载apache-tomcat-8.0.46.tar.gz
MySQL https://dev.mysql.com/downloads/repo/yum/ 选择下载mysql57-community-release-el7-11.noarch.rpm
Redis https://redis.io/download 选择下载redis-4.0.2.tar.gz
安装jdk:
chmod +x jdk-8u144-linux-x64.rpm //添加可执行权限
rpm -ivh jdk-8u144-linux-x64.rpm //安装RPM软件包
java –version //查看java的版本信息,若出现版本信息则成功
安装Mysql:
rpm -Uvh mysql57-community-release-el7-11.noarch.rpm //安装用来配置mysql的yum源的rpm包
yum install mysql-community-server //安装Mysql
这一步可能会报错Error:Unable to find a match: mysql-community-server,需要执行以下语句安装:
yum module disable mysql //先禁用本地的 MySQL 模块再安装
yum -y install mysql-community-server
service mysqld start //开启mysql服务
ps -ef | grep mysqld //查看是否启动成功(应显示mysql的进程)
grep ‘temporary password’ /var/log/mysqld.log //mysql安装成功后创建的超级用户’root’@‘localhost’的密码会被存储在/var/log/mysqld.log,可以使用如下命令查看密码
mysql -uroot -p //使用mysql生成的’root’@‘localhost’用户和密码登录数据库
ALTER USER ‘root’@‘localhost’ IDENTIFIED BY ‘123654’; //修改密码
这里如果密码过于简单,可能会报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements,使用以下语句:
SHOW VARIABLES LIKE 'validate_password%'; //查看 mysql 初始的密码策略(在这之前需要先把密码改成合适的才能继续操作,比如改为Dingmin@111)
set global validate_password.length=6; //根据不同的参数修改设置
set global validate_password.mixed_case_count=0;
set global validate_password.policy=LOW;
set global validate_password.special_char_count=0;
ALTER USER ‘root’@‘localhost’ IDENTIFIED BY ‘123654’; //重新修改密码
去阿里云开通端口的远程访问,包括22 3389 80 3306 6379
配置mysql远程访问:(文档上演示的语句在8执行总是报错,故使用以下语句)
use mysql; //指定数据库
select Host,User from user; //查询用户访问权限,此时发现显示的用户都是只有localhost可以访问
update user set host = '%' where user = 'root'; //允许root用户任何远程访问。%代表允许所有的远程主机进行连接
grant ALL on *.* to `root`@`%` with grant option; //授权
flush privileges; //刷新权限。。刷新以后就可以从本地navicat连上阿里云的数据库了
mysql -uroot -P3306 -h106.14.18.149 -p //这里也可以考虑从本地的cmd进入远程的mysql。但是由于本地使用的mysql版本过低,此处连接失败。等以后两者mysql版本都在8.0以上再验证
安装redis:
tar -zxvf redis-6.2.5.tar.gz //解压redis安装包,会在当前文件夹生成redis-6.2.5文件夹
设置redis以支持远程登录
vi redis-6.2.5/redis.conf //编辑该文件
将bind 127.0.0.1这句话用井号注释掉,这样就能支持远程连接了(按/进入查找功能,查找bind,修改为#bind 127.0.0.1)
将daemonize的属性值改为yes,以支持redis作为守护进程一直跑在后台(编辑结束按esc退出,按:wq保存退出 :wq!强制保存退出 :w保存但不退出 :q不保存并退出 :q!不保存并强制退出)
make //进入redis-6.2.5文件夹,安装
src/redis-server redis.conf //启动redis服务(此操作并未有任何输出,与文档显示有差异)
src/redis-cli //通过redis-cli连接到redis服务器。当输入ping 得到pong的回应之后,证明redis配置已经完成
安装tomcat:
tar -zxvf apache-tomcat-8.5.37.tar.gz //解压tomcat,生成文件夹apache-tomcat-8.5.37
./apache-tomcat-8.5.37/bin/startup.sh //启动tomcat,此时会显示tomcat started
DOWN 返回