Tmall_SSM

技术栈 Spring MVC+ Mybatis + Spring + Jsp + Tomcat , 是 Java Web 入门非常好的练手项目

效果展示:

模仿天猫前台

项目简介

关联项目

github - 天猫 JavaEE 项目

github - 天猫 SSH 项目

github - 天猫 SSM 项目

之前使用 JavaEE 整套技术和 SSH 框架来作为解决方案,实现模仿天猫网站的各种业务场景,现在开始使用 SSM 框架技术。

项目用到的技术如下:

Java: Java SE基础

前端: HTML,CSS, JavaScript, JQuery,AJAX, Bootstrap

J2EE:Tomcat, Servlet, JSP, Filter

框架:SpringSpring MVCMybatisSSM整合

数据库:MySQL

开发工具: IDEA ,Maven

表结构

建表sql 已经放在 Github 项目的 /sql 文件夹下

表名 中文含义 介绍
Category 分类表 存放分类信息,如女装,平板电视,沙发等
Property 属性表 存放属性信息,如颜色,重量,品牌,厂商,型号等
Product 产品表 存放产品信息,如LED40EC平板电视机,海尔EC6005热水器
PropertyValue 属性值表 存放属性值信息,如重量是900g,颜色是粉红色
ProductImage 产品图片表 存放产品图片信息,如产品页显示的5个图片
Review 评论表 存放评论信息,如买回来的蜡烛很好用,么么哒
User 用户表 存放用户信息,如斩手狗,千手小粉红
Order 订单表 存放订单信息,包括邮寄地址,电话号码等信息
OrderItem 订单项表 存放订单项信息,包括购买产品种类,数量等

Category-分类 Product-产品
Category-分类 Property-属性
Property-属性 PropertyValue-属性值
Product-产品 PropertyValue-属性值
Product-产品 ProductImage-产品图片
Product-产品 Review-评价
User-用户 Order-订单
Product-产品 OrderItem-订单项
User-用户 OrderItem-订单项
Order-订单 OrderItem-订单项
User-用户 User-评价

以上直接看可能暂时无法完全理解,结合后面具体到项目的业务流程就明白了。


开发流程

首先使用经典的 SSM 模式进行由浅入深地开发出第一个分类管理模块 ,

然后分析这种方式的弊端,再对其进行项目重构,使得框架更加紧凑,后续开发更加便利和高效率。

分类管理模块

Category 实体类

准备 Category 实体类,定义对应的字段即可。

举个例子,对于 分类 / category 的 实体类 和 表结构 设计如下:


Mapper 接口

public interface CategoryMapper {
List<Category> list();
}

CategoryMapper.xml 指定映射的 sql 和结果集

com.caozhihu.tmall.mapper.CategoryMapper 对应上面的 Mapper 接口。mybatis 的 sql 是手打的,还好有逆向工程,后面重构会讲。

<mapper namespace="com.caozhihu.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
</select>
</mapper>

CategoryService 接口
public interface CategoryService{
List<Category> list();
}

CategoryServiceImpl 实现类
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
public List<Category> list(){
return categoryMapper.list();
};
}

在 list() 方法中,通过其自动装配的一个 CategoryMapper 对象的 list() 方法来获取所有的分类对象。


CategoryController 控制类

@Controller //声明当前类是一个控制器
@RequestMapping("") //访问的时候无需额外的地址
public class CategoryController {
@Autowired //自动装配进 categoryService 接口
CategoryService categoryService; @RequestMapping("admin_category_list")
public String list(Model model){
List<Category> cs= categoryService.list();
model.addAttribute("cs", cs);
return "admin/listCategory";
}
}

在list方法中,通过 categoryService.list() 获取所有的 Category 对象,然后放在 "cs" 中,并服务端跳转到“admin/listCategory” 视图。


jdbc.properties 数据库配置文件

#数据库配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tmall_ssm?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=admin

applicationContext.xml

这里配置使用了阿里巴巴的 druid 数据库连接池,这些配置基本都是固定写法,PSCache 就是 PreparedStatement 缓存,据说可以大幅提升性能。

<beans>
<!-- 启动对注解的识别 -->
<context:annotation-config/>
<context:component-scan base-package="com.caozhihu.tmall.service"/> <!-- 导入数据库配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1"/>
<property name="minIdle" value="1"/>
<property name="maxActive" value="20"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true"/>
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20"/>
</bean> <!--Mybatis的SessionFactory配置-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="com.caozhihu.tmall.pojo"/>
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<array>
<value>classpath:com/caozhihu/tmall/mapper/*.xml</value>
<value>classpath:mapper/*.xml</value>
</array>
</property>
<!--分页插件-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
</value>
</property>
</bean>
</array>
</property>
</bean> <!--Mybatis的Mapper文件识别,mybatis-spring提供了MapperScannerConfigurer这个类,
它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.caozhihu.tmall.mapper"/>
</bean>
</beans>

这里只放了核心配置部分,头部命名空间已省略


springMVC.xml
<beans>
<!--启动注解识别-->
<context:annotation-config/>
<context:component-scan base-package="com.caozhihu.tmall.controller">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<mvc:annotation-driven/> <!--开通静态资源的访问-->
<mvc:default-servlet-handler/> <!-- 视图定位 例如 admin/listCategory 会被定位成 /WEB-INF/jsp/admin/listCategory.jsp-->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean> <!-- 对上传文件的解析-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
</beans>

web.xml

web.xml 主要提供如下功能

  1. 指定 spring 的配置文件为 classpath 下的 applicationContext.xml
  2. 设置中文过滤器
  3. 指定 spring mvc 配置文件为 classpath 下的 springMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5"> <!-- spring的配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!--中文过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- spring mvc核心:分发servlet -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- spring mvc的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

访问 jsp 显示数据

Controller 中的 Model 携带数据跳转到 jsp ,作为视图,担当的角色是显示数据,借助 JSTL 的 c:forEach 标签遍历从 CategoryController.list() 传递过来的集合。

管理分类剩下部分就不展开了

完整的CategoryMapper.xml代码如下

<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select> <select id="total" resultType="int">
select count(*) from category
</select> <insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" >
insert into category ( name ) values (#{name})
</insert> <delete id="delete">
delete from category where id= #{id}
</delete> <select id="get" resultType="Category">
select * from category where id= #{id}
</select> <update id="update" parameterType="Category" >
update category set name=#{name} where id=#{id}
</update>
</mapper>

完整的CategoryMapper接口代码如下

public interface CategoryMapper {
List<Category> list(Page page);
int total();
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}

完整的CategoryService接口代码如下

public interface CategoryService{
int total();
List<Category> list(Page page);
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}

完整的CategoryServiceImpl实现类代码就不放着了,只是实现了每个方法,并在其中调用对应的 CategoryMapper 方法而已,如下:

public List<Category> list(Page page) { return categoryMapper.list(page); }

思路流程图

项目重构

分类管理中的 CategoryMapper.xml 使用很直接的 SQL 语句开发出来,这样的好处是简单易懂,便于理解。可是,随着本项目功能的展开和复杂度的提升,使用这种直接的SQL语句方式的开发效率较低,需要自己手动写每一个SQL语句,而且其维护起来也比较麻烦。

所以我们做进一步的改进,主要是在分页方式和逆向工程方面做了重构。

  1. 分页方式

    目前的分页方式是自己写分页对应的 limit SQL 语句,并且提供一个获取总数的 count(*) SQL。 不仅如此, mapper, service, service.impl 里都要提供两个方法:

    list(Page page);

    count();

    分类是这么做的,后续其他所有的实体类要做分页管理的时候都要这么做,所以为了提高开发效率,把目前的分页方式改为使用 pageHelper 分页插件来实现。

  2. 逆向工程

    目前分类管理中 Mybatis 中相关类都是自己手动编写的,包括:Category.java, CategoryMapper.java和CategoryMapper.xml。

    尤其是 CategoryMapper.xml 里面主要是SQL语句,可以预见在接下来的开发任务中,随着业务逻辑的越来越复杂,SQL 语句也会越来越复杂,进而导致开发速度降低,出错率增加,维护成本上升等问题。

    为了解决手动编写 SQL 语句效率低这个问题,我们对 Mybatis 部分的代码,使用逆向工程进行重构。

    所谓的逆向工程,就是在已经存在的数据库表结构基础上,通过工具,自动生成 Category.java, CategoryMapper.java 和 CategoryMapper.xml,想想就很美好是吧。


pageHelper 分页

因为使用插件可以获取总数信息和实现分页查询了,所以关于分页操作的部分配置和代码要做修改。

修改 CategoryMapper.xml

  1. 去掉 total SQL 语句
  2. 修改 list SQL 语句,去掉其中的 limit
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
</select> <insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" >
insert into category ( name ) values (#{name})
</insert> <delete id="delete">
delete from category where id= #{id}
</delete> <select id="get" resultType="Category">
select * from category where id= #{id}
</select> <update id="update" parameterType="Category" >
update category set name=#{name} where id=#{id}
</update>
</mapper>

使用 PageHelper 提供的方法进行分页查询

CategoryMapper 接口 /CategoryService 接口 / CategoryServiceImpl 类 进行如下操作:

  1. 去掉 total() 方法
  2. 去掉 list(Page page) 方法
  3. 新增 list() 方法

使用分页插件后的 CategoryController.list()方法

@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService; @RequestMapping("admin_category_list")
public String list(Model model,Page page){
PageHelper.offsetPage(page.getStart(),page.getCount());
List<Category> cs= categoryService.list();
int total = (int) new PageInfo<>(cs).getTotal();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
}

在 applicationContext.xml 配置 pagehelper 插件

其实在上面显示的已经是配置过插件了,这里再提一下,就是在 SqlSessionFactoryBean 命名空间内设置一个 plugins 的属性。

<!--Mybatis的SessionFactory配置-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
</value>
</property>
</bean>
</array>
</property>

Mybatis 逆向工程

MybatisGenerator 插件是 Mybatis 官方提供的,这个插件存在一个问题 ,即当第一次生成了CategoryMapper.xml 之后,再次运行会导致 CategoryMapper.xml 生成重复内容,而影响正常的运行。

为了解决这个问题,需要自己写一个小插件类 OverIsMergeablePlugin 。

OverIsMergeablePlugin

这是复制别人的,具体原理还没研究。

public class OverIsMergeablePlugin extends PluginAdapter {
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
try {
Field field = sqlMap.getClass().getDeclaredField("isMergeable");
field.setAccessible(true);
field.setBoolean(sqlMap, false);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}

generatorConfig.xml 指定生成策略

这里提供一部分代码,具体的在 github

<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!--避免生成重复代码的插件-->
<plugin type="com.caozhihu.tmall.util.OverIsMergeablePlugin"/>
<!--是否在代码中显示注释-->
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost/tmall_ssm"
userId="root" password="admin">
</jdbcConnection>
<!--该属性可以控制是否强制DECIMAL和NUMERIC类型的字段转换为Java类型的java.math.BigDecimal,默认值为false,一般不需要配置。-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成pojo类存放位置-->
<javaModelGenerator targetPackage="com.caozhihu.tmall.pojo" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成xml映射文件存放位置-->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成mapper类存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.caozhihu.tmall.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator> <!--生成对应表及类名-->
<table tableName="category" domainObjectName="Category" enableCountByExample="false"
enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true"
selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"/>
</table>

MybatisGenerator 生成执行类

运行即生成 mapper,pojo,xml 文件,核心代码如下

List<String> warnnings = new ArrayList<>();
boolean overwrite = true;
InputStream is = MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream();//获取配置文件对应路径的输入流
ConfigurationParser configurationParser = new ConfigurationParser(warnnings);
Configuration configuration = configurationParser.parseConfiguration(is);
is.close(); DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(configuration, callback, warnnings);
myBatisGenerator.generate(null);

自动生成的 CategoryMapper.xml

这是插件自动生成的 xml,与我们自己手动写的也差不了多少,主要区别在于提供了一个 id="Example_Where_Clause" 的 SQL,借助这个可以进行多条件查询。


自动生成的 pojo 类

MybatisGenerator 会生成一个类叫做 XXXXExample 的。 它的作用是进行排序,条件查询的时候使用。

在分类管理里用到了排序,但是没有使用到其条件查询,在后续的属性管理里就会看到其条件查询的用法了。


自动生成的 mapper 接口

与手动编写的 CategoryMapper 对比,CategoryMapper 也是提供 CURD 一套,不过方法名发生了变化,比如:

delete() 叫做 deleteByPrimaryKey(),

update 叫做 updateByPrimaryKey(),

除此之外,还提供了一个 updateByPrimaryKeySelective() 方法,其作用是只更新,即只修改新插入的不为 null 的字段。(比如当前数据是 {name,age} ,插入新数据是 {newName,null},如果使用此方法,则插入之后数据变为 {newName,age} 而不是 {newName,null})

还有个改动是 list() 方法 ,变成了selectByExample(CategoryExample example);

修改 CategoryServiceImpl 实现类

因为 CategoryMapper 的方法名发生了变化,所以 CategoryServiceImpl 要做相应的调整。

值得一提的是list方法:

public List<Category> list() {
CategoryExample example =new CategoryExample();
example.setOrderByClause("id desc");
return categoryMapper.selectByExample(example);
}

按照这种写法,传递一个 example 对象,这个对象指定按照 id 倒排序来查询

我查看了 xml 里的映射, 在对应的查询语句 selectByExample 里面,

会判断 orderByClause 是否为空,如果不为空就追加 order by ${orderByClause}

这样如果设置了 orderByClause 的值为“id desc” ,执行的 sql 则会是 order by id desc

然后,我们再根据数据库字段,一次性生成所有的 实体类,example 类,mapper 和 xml,如果需要定制,直接在生成的东西上修改就行了,真是舒服啊。


后台还有其他管理页面的,比如属性管理、产品管理等,由于篇幅原因,具体的请移步github-Tmall_SSM项目

前台页面展示

此处是 SSH 跑起来截的图,SSM 版本目前只做了后台,前台未做,敬请期待...

本文所讲不足整个项目的 1/10 ,有兴趣的朋友请移步 github 项目的地址

参考

天猫SSM整站学习教程 里面除了本项目,还有 Java 基础,前端,Tomcat 及其他中间件等教程, 可以注册一个账户,能保存学习记录。

JavaWeb入门_模仿天猫整站Tmall_SSM实践项目的更多相关文章

  1. JavaWeb入门_模仿天猫整站Tmall_JavaEE实践项目

    Tmall_JavaEE 技术栈 Servlet + Jsp + Tomcat , 是Java Web入门非常好的练手项目 效果展示: 模仿天猫前台 模仿天猫后台 项目简介 关联项目 github - ...

  2. JavaWeb入门_模仿天猫整站Tmall_SSH实践项目

    Tmall_SSH 技术栈 Struts2 + Hibernate + Spring + Jsp + Tomcat , 是 Java Web 入门非常好的练手项目 效果展示: 模仿天猫前台 模仿天猫后 ...

  3. 模仿天猫实战【SSM版】——项目起步

    前言:现在自己的学习似乎遇到了瓶颈,感觉学习了 SSM 之后有一些迷茫,不知道接下来该往哪里去努力了,我觉得这是个很不好的状态,为了度过这段时期,我准备把天猫模仿下来(给自己找点事做)之后开始去巩固 ...

  4. scrapy进阶(CrawlSpider爬虫__爬取整站小说)

    # -*- coding: utf-8 -*- import scrapy,re from scrapy.linkextractors import LinkExtractor from scrapy ...

  5. 前端到后台ThinkPHP开发整站--php开发案例

    前端到后台ThinkPHP开发整站--php开发案例 总结 还是需要做几个案例,一天一个为佳,那样才能做得快. 从需求分析着手,任务体系要构建好,这样才能非常高效. 转自: 前端到后台ThinkPHP ...

  6. 网站seo整站优化有什么优势

    http://www.wocaoseo.com/thread-314-1-1.html       现在很多企业找网络公司做网站优化,已经不再像以前那样做目标关键词,而是通过整站优化来达到企业营销目的 ...

  7. DEDE整站动态化或整站静态化设置方法,织梦栏目批量静态/动态方法

    跟版网建站接到一个朋友提问,100多各栏目全部要从动态变成静态,里面的文章也要静态化,如何更快捷的设置dede的静态化或者动态化呢? 直接用DEDE后台的SQL命令行工具, SQL语句: DEDE整站 ...

  8. [参考]wget下载整站

    wget -m -e robots=off -U "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.6) Gecko/200 ...

  9. java开发_模仿百度文库_OpenOffice2PDF_注意事项

    在模仿百度文库的操作过程中,有很多朋友反映出来的一些问题,是我想起了写这篇blog. 主要是让大家在做的过程中注意一些东西,否则达不到想要的效果. 第一步:我们先从 java开发_模仿百度文库_Ope ...

随机推荐

  1. WPF 曲线图表控件(自制)(一)

    原文:WPF 曲线图表控件(自制)(一) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/775092 ...

  2. HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )

    Sum of divisors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. Enabling granular discretionary access control for data stored in a cloud computing environment

    Enabling discretionary data access control in a cloud computing environment can begin with the obtai ...

  4. Atitit.故障排除系列---php 计划网站数据库错误排除过程

    Atitit.故障排除系列---php 计划网站数据库错误排除过程 Php页面报告的错误不能定位到myusql的db配置上...字说是db conn err Mysql 接入错误...大概查看哈能不能 ...

  5. WCF寄宿与IIS里时遇到的问题

    [问题总结]WCF寄宿与IIS里时遇到的问题 最近在公司做了一个小的视频处理网站,由于视频处理,网站在不同的服务器上,所以处理视频的时候得在网站服务器上通过wcf请求视频处理服务器处理视频,并将结果返 ...

  6. matlab 高阶(一) —— assignin与evalin

    1. assignin assignin(ws, 'var', val) 将 val 值赋值给 ws 空间中的 var 变量,注意这里的变量,必须是 array 类型,而不可以是包含下标索引,如果在指 ...

  7. WPF 导出资源文件

    在wpf开发中我们可以把各种文件.图片打包到项目中也就是应用程序资源文件,然后在项目中可以通过特定的uri格式去调用.那有些时候为了方便我们可能想要在程序中将资源文件导出来使用,那么怎么做呢? 第 1 ...

  8. ASP.NET Core 基础教程 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 基础教程 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 是对 ASP.NET 有重大意义的一次重新设计.本章节我们将介绍 A ...

  9. Alamofire - 优雅的处理 Swift 中的网络操作

    网络处理,应该是我们平时开发的时候最常用到的操作.比如读取 JSON 数据,下载图片,这些操作都要和网络打交道,一个高效稳定的网络操作库对于提升我们日常的开发效率有着非常关键的作用.Alamofire ...

  10. android studio中使用9-patch报错mergeDebugResource及Duplicate resources错误处理

    由于项目中新导入了两张图片,进行9-patch之后,文件名称包含XXXX.9.png , 而android studio 对资源文件的名称有要求仅支持[A-Z][a-z][0-9]格式  而XXX.9 ...