Spring MVC起步

此文只用做慕课网 http://www.imooc.com/learn/47 笔记,如需转载请标明出自慕课网

源码地址:
https://github.com/alexnest/spring-mvc-study

在配置与使用maven中,遇到的问题参考了以下网址:
maven下载jar包速度慢
http://blog.csdn.net/u010717403/article/details/52188496
maven创建项目命令失败
http://blog.csdn.net/zgmzyr/article/details/6931957
http://www.cnblogs.com/candle806/p/3439469.html
http://tieba.baidu.com/p/2804486258
maven报字符编码错误
http://capslk.iteye.com/blog/1419958

Spring MVC简介

前端控制器

MVC是开发web应用程序的通用架构方式,下图为spring团队贡献给java社区的一种设计模式
Spring MVC架构视图

用户发起请求,通过httprequest到达Front Controller,Front Controller根据业务需求把任务指派给相应的Controller进行处理,Controller经过业务处理把最后结果包装成model返回给Front Controller,Front Controller再把model分发给对应的View templdate,View Template最终把model包装成页面呈现出来。

mvc的本质:
MVC的核心思想是业务数据的抽取同业务数据呈现相分离

MVC概念

MVC的组成:
MVC由3个英文单词表示Model,View,Controller。
View:视图层,为用户提供UI,重点关注数据的呈现。
Model:模型层,业务数据的信息表示,关注支撑业务的信息构成,通常是多个业务实体的组合。
Controller:控制层,调用业务逻辑产生合适的数据(Model) 传递数据给视图层用于呈现。

什么是MVC
MVC是一种架构模式
程序分层,分工合作,既相互独立,又协同工作。
MVC是一种思考方式
需要将什么信息展示给用户?如何布局?调用哪些业务逻辑?

Spring MVC的基本概念

静态概念

DispatcherServlet
这里写图片描述

DispatcherServlet就是Spring的Front Controller(前端控制器),用户请求经过DispatcherServlet选择对应的Controller,Controller经过业务处理把返回结果通过DespatcherServlet包装成Model,Model通过DispatcherServlet把Model分发给对应的View,最终给用户返回视图。

Controller
这里写图片描述

Controller生成Model

HandlerAdapter
这里写图片描述
Handler是DispatcherServlet内部使用的一个类,是Contoller的一个表现形式。事实上Spring MVC没有一个叫controller的接口,@controller是Spring MVC为识别Controller引入的一个标注。既然没有类似于Controller的一个接口,那Spring MVC怎么去识别Controller的呢?答案就是handler,在DispatcherServlet调用的Controller其实是以Handler的形式出现的。什么是HandlerAdapter呢?Java的命名知识又可以用上了,是一个适配器模式。就是把不同的Handler适配成可以供DispatcherServlet可以使用的Handler,这样,DispathcerServlet就可以很轻松地调用我们的控制器。

HandlerInterceptor
是拦截器,在我们需要拦截对象的两侧加入一些料,它是一个Interface,有3个方法,preHandler,postHandler,afterCompletion。

HandlerMapping
Handler是Dispatcher调用Controller的一种中间过度对象,HandlerMapping就是DispatcherServlet和Controller之间映射关系的一种类。
这里写图片描述

HandlerExecutionChain
Handler执行后返回给我们的实际包括了HandlerInterceptor和Controller,他们之间构成了一个执行链条。
这里写图片描述

该链条使用了java的反射机制reflect

ModelAndView
这里写图片描述

你可能在代码中看到有人使用Model,有人使用Map,DispatcherServlet都会通通转换成ModelAndView。

ViewResolver
他会告诉DispatcherServlet你需要用哪个视图来用做视图的呈现
这里写图片描述

View
包括jsp,jstl等等,用于页面呈现
这里写图片描述

动态概念

这里写图片描述
DispatcherServlet基于核心的地位,Controller是SpringMVC中的C,View是用户最终看到的东西。
访问过程:request从浏览器过来第一步先到达DispatcherServlet,DispatcherServlet以为是个Servlet,他可以拦截到所有的request,接着DispatcherServlet通过HandlerMapping找到对应的Controller和Interceptor,这时候就可以串联成一个HandlerExcutionChain,这样子作为一个Handler或者叫HandlerAdapter返回给DispatcherServlet,用于DispatcherServlet调用的目的。紧接着,DispatcherServlet会调用我们一般化的Handler或者HandlerAdapter。明显,Controller的目地是生成我们的模型(ModelAndView),为我们的页面提供一些显示的料,模型生成之后会返还给DispatcherServlet。跟着,ViewResovler出场,他告诉DispacherServlet哪些视图是用来解析当前这种场景的,DispacherServlet调用ViewResolver返回,因此DispatcherServlet调用ViewResolver返回view的对象传递给View,完成页面的呈现,这时候用户就可以看到页面了。

下图以另一种方式阐明SpringMVC模块的划分
这里写图片描述

配置Maven环境

Maven介绍

Maven是一个构建依赖管理工具。
以下从3方面描述Maven:
1.POM(Project Object Model)
2.Dependency Management(依赖管理)
3.Coordinates(坐标)

POM

POM是一个XML配置文件,配置版本,插件,依赖管理等项目内容。
Dependency(依赖),有些项目不是孤立存在,如下图,项目b,c分别依赖于项目a。而项目d又依赖于项目b,项目e又依赖于项目c。
这里写图片描述

Dependency

在Maven中很容易管理这种依赖关系,只需要配置dependency,如下图
这里写图片描述

Coordinates

Maven是如何实现依赖管理的呢?答案是坐标(Coordinates)。
groupId,artifactId,version,packaging这4个属性就构成了maven的坐标,这4个坐标是可以唯一标识一个产品的。packaing可以缺省值jar

Maven安装

下载并解压maven

在百度搜索引擎中搜索maven,即可发线maven的官方下载目录。打开maven官网 http://maven.apache.org/download.cgi ,在菜单栏中点击Download。
后缀含tar的是源码,含src的是linux版本。选择bin.zip后缀的文件下载。下载后解压到硬盘中。例如:解压到C:\MyApps\maven\apache-maven-3.3.9 文件目录下,如图
这里写图片描述

配置环境变量(M2_HOME,Path)

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
变量名 : M2_HOME
变量值 : C:\MyApps\maven\apache-maven-3.3.9
把%M2_HOME%\bin 添加进Path环境变量中 ,如下图
这里写图片描述

在cmd命令行中输入mvn - version验证maven是否安装成功

Maven配置

配置Maven配置文件(本地仓库路径,镜像)

此步骤不是必需步骤,但此步骤会使后续更加方便维护。

把配置文件拷贝到指定文件夹

把C:\MyApps\maven\apache-maven-3.3.9\conf目录下的settings.xml复制到%HOME%.m2(系统中可能没有HOME变量,这里的HOME变量指“\Documents and Settings\你的用户名”,例如:我本机的HOME是指“C:\Users\liangwei”,如此类推,就是把原解压目录中的C:\MyApps\maven\apache-maven-3.3.9\conf\settings.xml复制到C:\Users\liangwei.m2\settings.xml)。如果你刚刚仅仅安装了maven,但并没运行任何命令的话.m2目录不存在,你可手动创建这个目录。

修改配置文件

为什么我们需要把这个配置文件拷到%HOME%.m2目录下呢?因为我们有时需要对maven的版本进行升级。如果不把settings.xml拷到%HOME%.m2目录下,每次升级都需要改变配置文件。反之,我们不需要每次升级都更改settings.xml文件。

打开配置文件setting.xml
需要修改的地方有两个:

localRepository
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->

localRepository是个可选项,如果你不进行配置,他会把包安装在${user.home}/.m2/repository文件夹下。如果你希望下载的包放在其他位置,可以配置这一选项。

mirror
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>

maven核心仓库的镜像文件称之为mirror。世界各地有不同的mirror,针对你所在地区下载速度也不同。以下列出其他一些镜像仓库地址

<mirror>
      <id>CN</id>
      <name>OSChina Central</name>                                                                                                                       
      <url>http://maven.oschina.net/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>
</mirror>
<mirror>  
      <id>repo2</id>  
      <mirrorOf>central</mirrorOf>  
      <name>Human Readable Name for this Mirror.</name>  
      <url>http://repo2.maven.org/maven2/</url>  
</mirror>  
<mirror>  
      <id>net-cn</id>  
      <mirrorOf>central</mirrorOf>  
      <name>Human Readable Name for this Mirror.</name>  
      <url>http://maven.net.cn/content/groups/public/</url>   
</mirror>  
<mirror>  
      <id>ui</id>  
      <mirrorOf>central</mirrorOf>  
      <name>Human Readable Name for this Mirror.</name>  
     <url>http://uk.maven.org/maven2/</url>  
</mirror>  
<mirror>  
      <id>ibiblio</id>  
      <mirrorOf>central</mirrorOf>  
      <name>Human Readable Name for this Mirror.</name>  
     <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url>  
</mirror>  
<mirror>  
      <id>jboss-public-repository-group</id>  
      <mirrorOf>central</mirrorOf>  
      <name>JBoss Public Repository Group</name>  
     <url>http://repository.jboss.org/nexus/content/groups/public</url>  
</mirror>

用Maven创建项目

下载Eclipse

在百度中搜索eclipse,打开eclipse官网 http://www.eclipse.org/downloads/ ,根据自己的操作系统以及电脑是多少位选择对应的Eclipse进行下载(请选择Eclipse IDE for Java EE Developers,其他版本未必集成.m2)。

配置Eclipse

打开Eclipse,进入菜单 Window -> Preferences -> Maven -> Installations 把刚才解压的maven添加进此处

这里写图片描述

点击 Add 按钮,在对话框中输入maven的解压路径,前文中的解压路径是C:\MyApps\maven\apache-maven-3.3.9。添加完成后左侧表格中会显示刚才添加的路径。

进入菜单 Window -> Preferences -> Maven -> User Settings,确保文本框中的路径是刚才配置的 settings.xml 文件。
这里写图片描述

Apply -> OK 。至此,Eclipse环境搭建完成。

创建项目

在CMD命令行中运行以下命令创建项目

mvn archetype:generate -DgroupId=[your group id] -DartifactId=[your archetype id] -DarchetypeArtifactId=maven-archetype-webapp

e.g.

mvn archetype:generate -DarchetypeCatalog=internal -DgroupId=imooc-arthur -DartifactId=spring-mvc-study -DarchetypeArtifactId=maven-archetype-webapp

DgroupId:坐标
DartifactId:坐标(最终成为我们创建项目的根目录名称)

若以上命令创建项目失败,可参考 http://www.cnblogs.com/candle806/p/3439469.html
创建项目。

这里写图片描述

如上图,遇到 Y::直接回车,最后,mvn项目创建完成。

Hello Spring MVC

项目结构

这里写图片描述

导入项目

如果用命令行的方式成功项目后,需导入项目。打开Eclipse,File -> Import -> Maven -> Existing Maven Projects

创建缺失文件

右击工程,Properties -> Java Build Path。会看到java目录发生了缺失,我们需要手动添加java目录
这里写图片描述

配置pom.xml

<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>imooc-arthur</groupId>
    <artifactId>spring-mvc-study</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <commons-lang.version>2.6</commons-lang.version>
        <slf4j.version>1.7.6</slf4j.version>
        <spring.version>4.1.3.RELEASE</spring.version>
        <jackson.version>2.5.4</jackson.version>
    </properties>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>${spring.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>${commons-lang.version}</version>
        </dependency>


        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>utf8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.2.2.v20140723</version>
            </plugin>
        </plugins>
    </build>
</project>

properties:可以添加变量来替代我们用到的包版本。

dependencyManagement:配置依赖管理,maven为我们管理一些传递的依赖。假如我们的SpringMVC依赖了spring包,Hibernate也用到了Spring包,当这两个Spring依赖的版本不一样的时候,这时候依赖管理发生了作用。它会使用dependencyManagement中指定的版本的spring。

dependencies:依赖管理。可以为我们构建任意多的依赖的软件包。

plugins:可加入一些插件为我们提供一些额外的功能,这些插件本与应用无关。

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Spring MVC Study</display-name>
  <!-- Spring应用上下文, 理解层次化的ApplicationContext -->
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
  </context-param>

  <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>

  <!-- DispatcherServlet, Spring MVC的核心 -->
  <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- DispatcherServlet对应的上下文配置, 默认为/WEB-INF/$servlet-name$-servlet.xml
         -->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <!-- mvc-dispatcher拦截所有的请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

创建mvc-dispatcher-servlet.xml

在/WEB-INF/configs/spring/下创建mvc-dispatcher-servlet.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.xsd">

    <!-- 本配置文件是工名为mvc-dispatcher的DispatcherServlet使用, 提供其相关的Spring MVC配置 -->

    <!-- 启用Spring基于annotation的DI, 使用户可以在Spring MVC中使用Spring的强大功能。 激活 @Required 
        @Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注 -->
    <context:annotation-config />

    <!-- DispatcherServlet上下文, 只管理@Controller类型的bean, 忽略其他型的bean, 如@Service -->
    <context:component-scan base-package="com.imooc.mvcdemo">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- HandlerMapping, 无需配置, Spring MVC可以默认启动。 DefaultAnnotationHandlerMapping 
        annotation-driven HandlerMapping -->

    <!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
    <mvc:annotation-driven />

    <!-- 静态资源处理, css, js, imgs -->
    <mvc:resources mapping="/resources/**" location="/resources/" />


    <!-- 配置ViewResolver。 可以用多个ViewResolver。 使用order属性排序。 InternalResourceViewResolver放在最后。 -->
    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="htm" value="text/html" />
            </map>
        </property>

        <property name="defaultViews">
            <list>
                <!-- JSON View -->
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                </bean>
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true" />
    </bean>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsps/" />
        <property name="suffix" value=".jsp" />
    </bean>


    <!--200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="209715200" />
        <property name="defaultEncoding" value="UTF-8" />
        <property name="resolveLazily" value="true" />
    </bean>

</beans>

Spring MVC实操

从配置文件开始

通过mvn命令创建项目后,web.xml是maven自动生成的,应用了一个web-app_2.3.dtd的标准。
这里写图片描述
这里的页面会默认把EL表达式语言关闭,所以我们将这个东西替换掉,使用我们的2.4以上版本。
把web.xml配置成以下内容

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Spring MVC Study</display-name>
  <!-- Spring应用上下文, 理解层次化的ApplicationContext -->
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
  </context-param>

  <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>

  <!-- DispatcherServlet, Spring MVC的核心 -->
  <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- DispatcherServlet对应的上下文配置, 默认为/WEB-INF/$servlet-name$-servlet.xml
         -->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <!-- mvc-dispatcher拦截所有的请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在配置文件中注释可见“理解层次化的ApplicationContext”,什么是“理解层次化的ApplicationContext”?我们看到Spring应用上下文有一些自己的配置文件,DispatcherServlet也有自己的相关配置文件。这两组配置文件就构成了他们应用上的不同层次。
这里写图片描述
WebApplicationContext(s)可以看到有多个,我们可以理解为它是我们的根,它就是ContextLoaderListener加载形成的那个上下文,它为我们提供了所有应用公共所使用的一些组件,一些服务给我们的service层,dao层等等,这些服务应该是被整个应用所共享的,不应该局限在某个DispacherServlet上下文之中。另一个就是与特定DispatcherServlet相关的一个上下文,比如这里我们的MVCDispatcherServlet,与他们相关的特定的Controller,ViewResolver,HandlerMapping等等。我们有没有可能有多个DispatcherServlet呢?答案是肯定的。我们的互联网世界越来越复杂,例如慕课网会通过一个DispatcherServlet来分发学员的在线学习请求,也可能为机器提供webservice的方式,为他们提供课程的检索。机器的使用场景和人类的使用场景是不同的,这就需要不同的DispatcherServlet来做不同的分发。
在url-pattern中配置拦截请求的规则,这里配置成所有请求,并在init-param中配置初始化文件。初始化配置文件如下,路径为:WEB-INF\configs\spring\mvc-dispatcher-servlet.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.xsd">

    <!-- 本配置文件是工名为mvc-dispatcher的DispatcherServlet使用, 提供其相关的Spring MVC配置 -->

    <!-- 启用Spring基于annotation的DI, 使用户可以在Spring MVC中使用Spring的强大功能。 激活 @Required 
        @Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注 -->
    <context:annotation-config />

    <!-- DispatcherServlet上下文, 只管理@Controller类型的bean, 忽略其他型的bean, 如@Service -->
    <context:component-scan base-package="com.imooc.mvcdemo">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- HandlerMapping, 无需配置, Spring MVC可以默认启动。 DefaultAnnotationHandlerMapping 
        annotation-driven HandlerMapping -->

    <!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
    <mvc:annotation-driven />

    <!-- 静态资源处理, css, js, imgs -->
    <mvc:resources mapping="/resources/**" location="/resources/" />


    <!-- 配置ViewResolver。 可以用多个ViewResolver。 使用order属性排序。 InternalResourceViewResolver放在最后。 -->
    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="htm" value="text/html" />
            </map>
        </property>

        <property name="defaultViews">
            <list>
                <!-- JSON View -->
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                </bean>
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true" />
    </bean>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsps/" />
        <property name="suffix" value=".jsp" />
    </bean>


    <!--200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="209715200" />
        <property name="defaultEncoding" value="UTF-8" />
        <property name="resolveLazily" value="true" />
    </bean>

</beans>

applicationContext.xml是spring上下文相关的配置文件,它是整个spring通用的组件管理,具体配置如下,路径为:WEB-INF\configs\spring\applicationContext.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.xsd">

    <context:annotation-config />

    <context:component-scan base-package="com.imooc.mvcdemo">
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
</beans>

Controller,Binding,FileUpload,JSON

创建Course

package com.imooc.mvcdemo.model;

import java.util.List;

public class Course {

    // 课程Id
    private Integer courseId;
    // 课程名称
    private String title;
    // 图片路径
    private String imgPath;
    // 学习人数
    private Integer learningNum;
    // 课程时长
    private Long duration;
    // 课程难度
    private Integer level;
    // 课程难度描述
    private String levelDesc;
    // 课程介绍
    private String descr;
    // 课程提纲
    private List<Chapter> chapterList;

    public Integer getCourseId() {
        return courseId;
    }

    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getLearningNum() {
        return learningNum;
    }

    public void setLearningNum(Integer learningNum) {
        this.learningNum = learningNum;
    }

    public Integer getLevel() {
        return level;
    }

    public void setLevel(Integer level) {
        this.level = level;
    }

    public String getImgPath() {
        return imgPath;
    }

    public void setImgPath(String imgPath) {
        this.imgPath = imgPath;
    }

    public List<Chapter> getChapterList() {
        return chapterList;
    }

    public void setChapterList(List<Chapter> chapterList) {
        this.chapterList = chapterList;
    }

    public Long getDuration() {
        return duration;
    }

    public void setDuration(Long duration) {
        this.duration = duration;
    }

    public String getDescr() {
        return descr;
    }

    public void setDescr(String descr) {
        this.descr = descr;
    }

    public String getLevelDesc() {
        return levelDesc;
    }

    public void setLevelDesc(String levelDesc) {
        this.levelDesc = levelDesc;
    }

}

创建Chapter

package com.imooc.mvcdemo.model;



public class Chapter {

    private Integer id;
    private Integer courseId;
    private Integer order;
    private String title;
    private String descr;

//    private List<Section> sectionList;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getCourseId() {
        return courseId;
    }

    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }

    public Integer getOrder() {
        return order;
    }

    public void setOrder(Integer order) {
        this.order = order;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }



    public String getDescr() {
        return descr;
    }

    public void setDescr(String descr) {
        this.descr = descr;
    }

//  



}

Course2

package com.imooc.mvcdemo.model;


public class Course2 {

    // 课程Id
    private Integer courseId;
    // 课程名称
    private String title;
    // 图片路径
    private String imgPath;
    // 学习人数
    private Integer learningNum;
    // 课程时长
    private Long duration;
    // 课程难度
    private Integer level;
    // 课程难度描述
    private String levelDesc;
    // 课程介绍
    private String descr;
    // 课程提纲
//  private List<Chapter> chapterList;

    public Integer getCourseId() {
        return courseId;
    }

    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getLearningNum() {
        return learningNum;
    }

    public void setLearningNum(Integer learningNum) {
        this.learningNum = learningNum;
    }

    public Integer getLevel() {
        return level;
    }

    public void setLevel(Integer level) {
        this.level = level;
    }

    public String getImgPath() {
        return imgPath;
    }

    public void setImgPath(String imgPath) {
        this.imgPath = imgPath;
    }

//  public List<Chapter> getChapterList() {
//      return chapterList;
//  }
//
//  public void setChapterList(List<Chapter> chapterList) {
//      this.chapterList = chapterList;
//  }

    public Long getDuration() {
        return duration;
    }

    public void setDuration(Long duration) {
        this.duration = duration;
    }

    public String getDescr() {
        return descr;
    }

    public void setDescr(String descr) {
        this.descr = descr;
    }

    public String getLevelDesc() {
        return levelDesc;
    }

    public void setLevelDesc(String levelDesc) {
        this.levelDesc = levelDesc;
    }

}

创建Section

package com.imooc.mvcdemo.model;

public class Section {

    private Integer id;
    private Integer courseId;
    private Integer chapterId;
    private Integer order;
    private String  title;
    private Integer type;
    private String duration;
    private String filePath;


    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getCourseId() {
        return courseId;
    }
    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }
    public Integer getChapterId() {
        return chapterId;
    }
    public void setChapterId(Integer chapterId) {
        this.chapterId = chapterId;
    }
    public Integer getOrder() {
        return order;
    }
    public void setOrder(Integer order) {
        this.order = order;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getDuration() {
        return duration;
    }
    public void setDuration(String duration) {
        this.duration = duration;
    }
    public String getFilePath() {
        return filePath;
    }
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }



}

创建CourseService

package com.imooc.mvcdemo.service;

import org.springframework.stereotype.Service;

import com.imooc.mvcdemo.model.Course;

@Service
public interface CourseService {


    Course getCoursebyId(Integer courseId);

}

创建CourseServiceImpl

package com.imooc.mvcdemo.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.imooc.mvcdemo.model.Chapter;
import com.imooc.mvcdemo.model.Course;
import com.imooc.mvcdemo.service.CourseService;


@Service("courseService")
public class CourseServiceImpl implements CourseService {

    public Course getCoursebyId(Integer courseId) {

        Course course = new Course();

        course.setCourseId(courseId);
        course.setTitle("深入浅出Java多线程");
        course.setImgPath("resources/imgs/course-img.jpg");
        course.setLearningNum(12345);
        course.setLevel(2);
        course.setLevelDesc("中级");
        course.setDuration(7200l);
        course.setDescr("多线程是日常开发中的常用知识,也是难用知识。bala bala...");

        List<Chapter> chapterList = new ArrayList<Chapter>();

        warpChapterList(courseId,chapterList);

        course.setChapterList(chapterList);

        return course;
    }

    private void warpChapterList(Integer courseId,List<Chapter> chapterList) {
        Chapter chapter = new Chapter();
        chapter.setId(1);
        chapter.setCourseId(courseId);
        chapter.setOrder(1);
        chapter.setTitle("第1章 多线程背景知识介绍");
        chapter.setDescr("本章将介绍与多线程编程相关的背景概念"); 
        chapterList.add(chapter);

        chapter = new Chapter();
        chapter.setId(2);
        chapter.setCourseId(courseId);
        chapter.setOrder(2);
        chapter.setTitle("第2章 Java 线程初体验");
        chapter.setDescr("Java语言层面对线程的支持,如何创建,启动和停止线程。如何使用常用的线程方法。用隋唐演义理解线程的代码");
        chapterList.add(chapter);

        chapter = new Chapter();
        chapter.setId(3);
        chapter.setCourseId(courseId);
        chapter.setOrder(3);
        chapter.setTitle("第3章 Java 线程的正确停止");
        chapter.setDescr("本章讨论如何正确的停止一个线程,既要线程停得了,还得线程停得好。");       
        chapterList.add(chapter);

        chapter = new Chapter();
        chapter.setId(4);
        chapter.setCourseId(courseId);
        chapter.setOrder(4);
        chapter.setTitle("第4章 线程交互");
        chapter.setDescr("争用条件,线程的交互,及死锁的成因及预防。");      
        chapterList.add(chapter);

        chapter = new Chapter();
        chapter.setId(5);
        chapter.setCourseId(courseId);
        chapter.setOrder(5);
        chapter.setTitle("第5章 进阶展望");
        chapter.setDescr("简单介绍 Java 并发相关的类,及常用的多线程编程模型。");      
        chapterList.add(chapter);

    }
}

创建CourseController

package com.imooc.mvcdemo.controller;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.imooc.mvcdemo.model.Course;
import com.imooc.mvcdemo.service.CourseService;


@Controller
@RequestMapping("/courses")
// /courses/**
public class CourseController {

    private static Logger log = LoggerFactory.getLogger(CourseController.class);

    private CourseService courseService;

    @Autowired
    public void setCourseService(CourseService courseService) {
        this.courseService = courseService;
    }


    //本方法将处理 /courses/view?courseId=123 形式的URL
    @RequestMapping(value="/view", method=RequestMethod.GET)
    public String viewCourse(@RequestParam("courseId") Integer courseId,
            Model model) {


        log.debug("In viewCourse, courseId = {}", courseId);
        Course course = courseService.getCoursebyId(courseId);
        model.addAttribute(course);
        return "course_overview";
    }

    //本方法将处理 /courses/view2/123 形式的URL
    @RequestMapping("/view2/{courseId}")
    public String viewCourse2(@PathVariable("courseId") Integer courseId,
            Map<String, Object> model) {

        log.debug("In viewCourse2, courseId = {}", courseId);
        Course course = courseService.getCoursebyId(courseId);
        model.put("course",course);
        return "course_overview";
    }

    //本方法将处理 /courses/view3?courseId=123 形式的URL
    @RequestMapping("/view3")
    public String viewCourse3(HttpServletRequest request) {

        Integer courseId = Integer.valueOf(request.getParameter("courseId"));       
        Course course = courseService.getCoursebyId(courseId);
        request.setAttribute("course",course);

        return "course_overview";
    }

    @RequestMapping(value="/admin", method = RequestMethod.GET, params = "add")
    public String createCourse(){
        return "course_admin/edit";
    }

    @RequestMapping(value="/save", method = RequestMethod.POST)
    public String  doSave(@ModelAttribute Course course){       

        log.debug("Info of Course:");
        log.debug(ReflectionToStringBuilder.toString(course));

        //在此进行业务操作,比如数据库持久化
        course.setCourseId(123);
        return "redirect:view2/"+course.getCourseId();
    }

    @RequestMapping(value="/upload", method=RequestMethod.GET)
    public String showUploadPage(@RequestParam(value= "multi", required = false) Boolean multi){    
        if(multi != null && multi){
            return "course_admin/multifile";    
        }
        return "course_admin/file";     
    }

    @RequestMapping(value="/doUpload", method=RequestMethod.POST)
    public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{

        if(!file.isEmpty()){
            log.debug("Process file: {}", file.getOriginalFilename());
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\\temp\\imooc\\", System.currentTimeMillis()+ file.getOriginalFilename()));
        }

        return "success";
    }

    @RequestMapping(value="/doUpload2", method=RequestMethod.POST)
    public String doUploadFile2(MultipartHttpServletRequest multiRequest) throws IOException{

        Iterator<String> filesNames = multiRequest.getFileNames();
        while(filesNames.hasNext()){
            String fileName =filesNames.next();
            MultipartFile file =  multiRequest.getFile(fileName);
            if(!file.isEmpty()){
                log.debug("Process file: {}", file.getOriginalFilename());
                FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\\temp\\imooc\\", System.currentTimeMillis()+ file.getOriginalFilename()));
            }

        }

        return "success";
    }



    @RequestMapping(value="/{courseId}",method=RequestMethod.GET)
    public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
        return  courseService.getCoursebyId(courseId);
    }


    @RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
    public  ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
        Course course =   courseService.getCoursebyId(courseId);        
        return new ResponseEntity<Course>(course, HttpStatus.OK);
    }



}

创建HelloMvcController

package com.imooc.mvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

//告诉DispatcherServlet相关的容器, 这是一个Controller, 管理好这个bean哦
@Controller
//类级别的RequestMapping,告诉DispatcherServlet由这个类负责处理以跟URL。
//HandlerMapping依靠这个标签来工作
@RequestMapping("/hello")
public class HelloMvcController {

    //方法级别的RequestMapping, 限制并缩小了URL路径匹配,同类级别的标签协同工作,最终确定拦截到的URL由那个方法处理
    @RequestMapping("/mvc")
    public String helloMvc() {

        //视图渲染,/WEB-INF/jsps/home.jsp
        return "home";
    }

}

创建log4j.properties

在\spring-mvc-study-master\src\main\resources下创建log4j.properties

log4j.appender.Cons=org.apache.log4j.ConsoleAppender
log4j.appender.Cons.layout=org.apache.log4j.PatternLayout
log4j.appender.Cons.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n


# Root logger set to DEBUG using the A2 appender defined above.
log4j.rootLogger=info, Cons 
log4j.additivity=false

#Application Logger+
log4j.logger.com.imooc.mvcdemo=debug, Cons
log4j.logger.org.springframework=debug, Cons
log4j.additivity.com=false

创建样式文件及JSP页面

  • \spring-mvc-study-master\src\main\webapp\resources\css\main.css
@charset "UTF-8";  
/* CSS reset */
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{ margin: 0; padding: 0; }
fieldset,img{ border: 0; }
:focus{ outline: 0; }
address,caption,cite,code,dfn,em,strong,th,var,optgroup{ font-style: normal; font-weight: normal; }
h1,h2,h3,h4,h5,h6{ font-size: 100%; font-weight: normal; font-family: "Microsoft YaHei"; }
abbr,acronym{ border: 0; font-variant: normal; }
code,kbd,samp,tt{ font-size: 100%; }
input,button,textarea,select{ *font-size: 100%; border:none;}
body{ background:#fff; color:#5e5e5e; font: 14px/2em Microsoft YaHei,SimSun,Arial;}
ol,ul{ list-style: none; }
table{ border-collapse: collapse; border-spacing: 0; }
caption,th{ text-align: left; }
sup,sub{ font-size: 100%; vertical-align: baseline; }
:link, :visited, ins{ text-decoration: none; }
blockquote,q{ quotes: none; }
blockquote:before, blockquote:after, q:before, q:after{ content: ''; content: none; }
a:link, a:visited{ color: #5e5e5e;}
a:hover { color:#c9394a;}
a:active { color: #666;}
.clearfix:after{content:'\0020';display:block;height:0;clear:both;visibility:hidden;}
.clearfix{*zoom:1;}
.l{float:left;}
.r{float:right;}
.clear{ height:0; overflow:hidden; clear:both}
.hide{display:none;}
.btn.hide{display:none;}
a.hidefocus { outline: none; } 
button.hidefocus::-moz-focus-inner { border:none; } 
a:focus {outline:none;-moz-outline:none;} 
input,textarea {outline:none;} 
h2 { font-size: 20px; }
h3 { font-size: 16px; line-height: 32px; }
h5 { font-size: 14px; line-height: 28px; }
/*border && padding*/
.img_border { border: 4px solid #fff; border-radius: 1px;}
.bb { border-bottom: 1px solid #d2d2d2 }
.bt { border-top: 1px solid #d2d2d2 }
.pt15 { padding-top: 15px; }
.pb15 { padding-bottom: 15px; }
.p15{ padding:0 15px}
/*颜色定义*/
.color-gray,a.color-gray:link,a.color-gray:visited{color:#b7bcc0;}html,
body {
  font: 14px/1.5 "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", "微软雅黑", Tahoma, Arial, sans-serif;
  color: #14191e;
}
body {
  overflow-y: scroll;
}
body {
  background-color: #edeff0;
}
a:link,
a:visited {
  color: #14191e;
}
a:hover,
a:active {
  color: #cc0000;
}
.clearfix:after {
  content: '\0020';
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}
.clearfix {
  *zoom: 1;
}
.l {
  float: left;
}
.r {
  float: right;
}
.hide {
  display: none;
}
.hide-text {
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}
.newcontainer,
.page-container {
  margin: 0 auto;
  width: 1200px;
}
.container {
  margin: 0 auto;
}
.container {
  width: 1200px;
}
#main {
  min-height: 750px;
  padding: 20px 0;
}
.waper {
  width: 1200px;
  margin: 0 auto;
}
.shadow {
  -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.text-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#header {
  background: #000000;
}
#nav {
  height: 60px;
  margin: 0 auto;
  position: relative;
  z-index: 1000;
}
.logo {
  float: left;
}
#logo a,
.logo a {
  display: block;
  height: 60px;
  width: 140px;
  background: url(/static/img/common/logo.png) no-repeat center center;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}
.logo a {
  -webkit-transition: background-color 0.2s;
  -moz-transition: background-color 0.2s;
  transition: background-color 0.2s;
}
.logo a:hover {
  background-color: #363c41;
}
.nav-item li {
  float: left;
  width: 100px;
}
.nav-item a {
  display: block;
  color: #787d82;
  text-align: center;
  font-size: 14px;
  height: 60px;
  line-height: 60px;
  -webkit-transition: background-color 0.3s;
  -moz-transition: background-color 0.3s;
  transition: background-color 0.3s;
}
.nav-item a:hover {
  color: #fff;
  background-color: #363c41;
}
/*.nav-item-mycourse a {
  width: 120px;
}*/
/*全局搜索*/
.search-area {
  float: right;
  position: relative;
  height: 30px;
  width: 240px;
  margin: 15px 0;
  margin-right: 20px;
  background: #363c41;
}
.search-area .search-input {
  padding: 5px 10px;
  width: 190px;
  height: 20px;
  line-height: 20px;
  font-size: 12px;
  float: left;
  border: 0;
  background: #363c41;
  color: #14191e;
  -webkit-transition: background-color 0.3s;
  -moz-transition: background-color 0.3s;
  transition: background-color 0.3s;
}
.search-area .search-input:-moz-placeholder {
  color: #787d82;
}
.search-area .search-input::-moz-placeholder {
  color: #787d82;
  opacity: 1;
}
.search-area .search-input:-ms-input-placeholder {
  color: #787d82;
}
.search-area .search-input::-webkit-input-placeholder {
  color: #787d82;
}
.search-area .search-input.placeholder {
  color: #787d82;
}
.search-area .btn_search {
  float: right;
  cursor: pointer;
  width: 30px;
  height: 30px;
  -webkit-transition: background-color 0.3s;
  -moz-transition: background-color 0.3s;
  transition: background-color 0.3s;
}
.search-area .btn_search,
.search-area .course,
.search-area .wenda {
  background: url(/static/img/gsearch-sprite.png) no-repeat 0 0;
}
.search-area.focus .search-input {
  color: #363d40;
  background: #fff;
}
.search-area.focus .btn_search {
  background-position: 0 -40px;
  background-color: #fff;
}
.search-area .search-area-result {
  position: absolute;
  left: 0px;
  top: 31px;
  width: 258px;
  margin-bottom: 20px;
  border: 1px solid #d3d3d3;
  border-top: none;
  background-color: #fff;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
  font-size: 12px;
  overflow: hidden;
  display: none;
  z-index: 1000;
}
.search-area .search-area-result dt,
.search-area .search-area-result dd {
  height: 40px;
  line-height: 40px;
}
.search-area .search-area-result dt {
  padding: 0 10px;
  color: #787d82;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-area .search-area-result dt span {
  color: #14191e;
}
.search-area .search-area-result dd a {
  padding: 0 10px 0 33px;
  display: block;
  width: auto;
  color: #787d82;
}
.search-area .search-area-result dd span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-area .search-area-result dd a:hover,
.search-area .search-area-result .curr a {
  color: #14191e;
  background-color: #edf0f2;
}
.search-area .course {
  background-position: 10px -80px;
}
.search-area .search-area-result .curr .course {
  background-position: 10px -130px;
}
.search-area .wenda {
  background-position: 10px -180px;
}
.search-area .search-area-result .curr .wenda {
  background-position: 10px -230px;
}
#login-area {
  float: right;
  position: relative;
}
.header-unlogin li {
  float: left;
}
.header-signin a,
.header-signup a {
  display: block;
  width: 60px;
  font-size: 14px;
  text-align: center;
  height: 60px;
  line-height: 60px;
  color: #787d82;
  -webkit-transition: background-color 0.2s;
  -moz-transition: background-color 0.2s;
  transition: background-color 0.2s;
}
.header-signin a:hover {
  color: #fff;
  background-color: #cc0000;
}
.header-signup a:hover {
  color: #fff;
  background-color: #363c41;
}
.logined > li {
  float: left;
}
.logined li > a {
  display: block;
  height: 60px;
  line-height: 60px;
  width: 60px;
  color: #787d82;
  text-align: center;
  -webkit-transition: background-color 0.2s;
  -moz-transition: background-color 0.2s;
  transition: background-color 0.2s;
}
.logined li > a:hover {
  color: #fff;
  background-color: #363c41;
}
.my_message a {
  background: url(/static/img/icon_msg.png) no-repeat center center;
}
.my_message a span {
  display: none;
}
.msg_icon {
  display: none;
  position: absolute;
  padding: 0px 4px;
  height: 16px;
  left: 32px;
  top: 10px;
  line-height: 14px;
  background: #c9394a;
  color: #fff;
  font-style: normal;
  font-size: 10px;
}
.my_mp span {
  display: block;
  line-height: 16px;
  color: #6c7072;
}
.my_mp .mp {
  padding-top: 12px;
  font-size: 12px;
}
.my_mp a:hover .mp_num {
  color: #fff;
}
.set_btn {
  right: 0px;
  cursor: pointer;
}
.set_btn a.hover {
  background-color: #363d40;
}
.set_btn img {
  border-radius: 22px;
  border: 2px solid #adb0b1;
  vertical-align: middle;
  display: inline-block;
  background: url(/static/img/menu_icon.png) no-repeat 0 0;
}
#nav_list {
  display: none;
  z-index: 999;
  width: 140px;
  position: absolute;
  top: 60px;
  right: 0px;
  background: #363c41;
  list-style: none;
}
#nav_list li a {
  border-top: 1px solid #4a5153;
  height: 39px;
  line-height: 39px;
  font-size: 14px;
  background-image: url(/static/img/menu_icon.png?t=10);
  background-repeat: no-repeat;
  display: block;
  color: #fff;
  text-align: left;
  padding: 0;
  padding-left: 47px;
  width: auto;
}
#nav_list a:hover {
  color: #fff;
  background-color: #4d5559;
}
#nav_list #my_space {
  padding: 0 18px;
  background-image: none;
  border: 0;
  height: 49px;
  line-height: 49px;
  text-align: center;
}
#nav_list .my_message {
  background-position: 19px -46px;
}
#nav_list #my_note {
  background-position: 19px -90px;
}
#nav_list #my_question {
  background-position: 19px -128px;
}
#nav_list #my_setting {
  background-position: 19px -167px;
}
#nav_list #my_logout {
  background-position: 19px -207px;
}
.myspace_remind {
  width: 10px;
  height: 10px;
  background: url(/static/img/space-remind.png) no-repeat 0 0;
  position: absolute;
  top: 10px;
  right: 10px;
}
/*footer*/
#footer {
  background: #000000;
  border-top: 1px solid #e2e4e6;
  font-size: 12px;
  color: #787d82;
  padding: 40px 0;
  min-width: 1200px;
}
#footer .footer_intro {
  border-right: 1px solid #363c41;
  width: 639px;
}
#footer p {
  margin-left: 180px;
  line-height: 1.7;
}
.footer_logo {
  float: left;
  background: url(/static/img/common/footer-sprite.png) 0 -230px no-repeat;
  height: 40px;
  width: 120px;
  margin: 0 20px;
}
#footer .des {
  width: 445px;
}
#footer .followus {
  padding-left: 30px;
}
.followus a {
  float: left;
  position: relative;
  width: 32px;
  height: 32px;
  background-image: url(/static/img/common/footer-sprite.png);
  background-repeat: no-repeat;
  margin: 3px 6px 0;
  opacity: 0.5;
  filter: alpha(opacity=50);
  -webkit-transition: opacity 0.2s;
  -moz-transition: opacity 0.2s;
  transition: opacity 0.2s;
}
#footer .followus a:hover {
  opacity: 1;
  filter: alpha(opacity=100);
}
.flw-weixin-box {
  position: absolute;
  display: none;
  width: 170px;
  height: 220px;
  left: -69px;
  bottom: 35px;
  background: url(/static/img/common/footer-sprite.png?1) no-repeat 0 0;
}
.followus .followus-weixin {
  background-position: 0 -279px;
}
.followus-weixin:hover .flw-weixin-box {
  display: block;
}
.followus .followus-weibo {
  background-position: 0 -321px;
}
.followus .followus-qzone {
  background-position: 0 -363px;
}
.friend-links {
  /*padding-top: 20px ;border-top:1px solid #4F5153;*/
  line-height: 60px;
}
.friend-links a {
  display: inline-block;
  margin-right: 20px;
}
.friend-links a:hover {
  text-decoration: underline;
  color: #000;
}
.friend-links dl {
  padding: 0 10px;
}
.friend-links dd {
  float: left;
  width: 160px;
}
#footer .footer_intro,
#footer .footer_link,
#footer .followus {
  float: left;
  height: 40px;
}
.footer_link ul {
  overflow: hidden;
  margin-top: -1px;
}
.footer_link a:link,
.footer_link a:visited,
.footer_link a:active {
  color: #787d82;
}
.footer_link a:hover {
  color: #fff;
}
#footer .footer_link {
  padding: 0 30px;
  width: 320px;
  border-right: 1px solid #363c41;
  line-height: 1.8;
}
#footer .footer_link li {
  width: 80px;
  text-align: center;
  float: left;
}
/*翻页*/
.page {
  margin: 25px 0 auto;
  overflow: hidden;
  clear: both;
  text-align: center;
}
.page-inner {
  padding: 0 20px;
}
.page a {
  display: inline-block;
  margin: 0 5px;
  padding: 0 5px;
  min-width: 20px;
  height: 29px;
  line-height: 30px;
  font-size: 14px;
  color: #787d82;
  text-align: center;
  border-bottom: 1px solid transparent;
  -webkit-transition: border-color 0.2s;
  -moz-transition: border-color 0.2s;
  transition: border-color 0.2s;
}
.page a:hover {
  border-color: #cc0000;
  color: #cc0000;
  text-decoration: none;
}
.page a.active {
  background: #cc0000;
  color: #ffffff;
  border-color: transparent;
}
.page span,
.page-disabled {
  display: inline-block;
  padding: 0 5px;
  min-width: 20px;
  height: 39px;
  line-height: 39px;
  font-size: 14px;
  color: #c8cdd2;
  text-align: center;
}
.page-first,
.page-last {
  width: 50px;
}
.page-prev,
.page-next {
  width: 70px;
}
.page .notmargin {
  margin-right: 0;
}
/* 
HTML structure:
<div class="panel">
  <div class="panel-heading">
    <h3 class="panel-title">Panel title</h3>
  </div>
  <div class="panel-body">
    Panel content
  </div>
  <div class="panel-footer">Panel footer</div>
</div>
panel-heading,
panel-body,
panel-footer all could be select use not necessary
*/
.bordered {
  border-bottom: solid 1px #d0d6d9;
}
.panel {
  -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  padding: 0 20px;
  color: #14191e;
  background-color: #ffffff;
  margin-bottom: 20px;
}
.panel-heading {
  border-bottom: solid 1px #d0d6d9;
}
.panel-title {
  height: 50px;
  line-height: 50px;
  font-size: 16px;
}
select {
  margin: 0;
  font-size: 100%;
  cursor: pointer;
  font-weight: normal;
  background-color: #fff;
  border: 1px solid #ccc;
  color: #555;
  display: inline-block;
  font-size: 14px;
  height: 30px;
  line-height: 30px;
  padding: 4px 6px;
  vertical-align: middle;
}
select:focus {
  outline: thin dotted #333;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
/*收藏*/
a.btn-add-collection {
  display: block;
  background: url(/static/img/course/new_add_collection.png) no-repeat 46px top;
  height: 32px;
  color: #909b9e;
  text-align: center;
  line-height: 35px;
}
a.btn-add-collection:hover {
  background-position: 46px -44px;
  color: #fff;
}
a.btn-remove-collection {
  background-position: 46px -88px;
  color: #909b9e;
}
a.btn-remove-collection:hover {
  background-position: 46px -130px;
}
.course-title .btn-add-collection {
  margin-top: 6px;
}
.videohead .btn-add-collection {
  margin-top: 20px;
}
.js-btn-collection .concerned-icon {
  margin-top: 34px;
  display: inline-block;
}
/*进度条*/
progress {
  display: inline-block;
  background: #f0f0f0;
  border: 0;
  height: 6px;
  color: #aad94a;
  /*IE10 #c9394a*/
  width: 400px;
}
progress::-webkit-progress-bar {
  background: #f0f0f0;
}
progress::-moz-progress-bar {
  background: #aad94a;
}
progress::-webkit-progress-value {
  background: #aad94a;
}
.progress {
  background: #f0f0f0;
  height: 6px;
  width: 400px;
  display: inline-block;
}
.progressBar {
  background: #aad94a;
  height: 6px;
}
.teacher-icon {
  width: 7px;
  margin-left: 5px;
  position: relative;
  top: 1px;
}
/*回到顶部*/
.elevator {
  position: fixed;
  right: 15px;
  bottom: 10px;
  z-index: 1030;
}
.elevator a {
  display: block;
  position: relative;
  margin: 1px 0;
  outline: none;
  height: 52px;
  width: 52px;
  -webkit-transition: background-position 0.15s;
  -moz-transition: background-position 0.15s;
  transition: background-position 0.15s;
  background: url(/static/img/common/elevator.png?1) no-repeat;
}
.elevator .elevator-diaocha {
  background-position: 0 -798px;
}
.elevator .elevator-diaocha:hover {
  background-position: 0 -984px;
}
.elevator .elevator-app-box {
  position: absolute;
  display: none;
  width: 172px;
  height: 194px;
  bottom: -10px;
  right: 46px;
  -webkit-transition: opacity 0.25s;
  -moz-transition: opacity 0.25s;
  transition: opacity 0.25s;
  opacity: 0;
  filter: alpha(opacity=0);
  background: url(/static/img/common/elevator.png) no-repeat 0 -222px;
}
.elevator .elevator-app {
  background-position: 0 -550px;
}
.elevator .elevator-app:hover {
  background-position: 0 -612px;
}
.elevator .elevator-app:hover .elevator-app-box {
  display: block;
  opacity: 1;
  filter: alpha(opacity=100);
}
.elevator .elevator-weixin-box {
  position: absolute;
  display: none;
  width: 172px;
  height: 212px;
  bottom: -10px;
  right: 46px;
  -webkit-transition: opacity 0.25s;
  -moz-transition: opacity 0.25s;
  transition: opacity 0.25s;
  opacity: 0;
  filter: alpha(opacity=0);
  background: url(/static/img/common/elevator.png) no-repeat 0 0;
}
.elevator .elevator-weixin {
  background-position: 0 -860px;
}
.elevator .elevator-weixin:hover {
  background-position: 0 -922px;
}
.elevator .elevator-weixin:hover .elevator-weixin-box {
  display: block;
  opacity: 1;
  filter: alpha(opacity=100);
}
.elevator .elevator-msg {
  background-position: 0 -426px;
}
.elevator .elevator-msg:hover {
  background-position: 0 -488px;
}
.elevator .elevator-top {
  background-position: 0 -674px;
}
.elevator .elevator-top:hover {
  background-position: 0 -736px;
}
a {
  outline: none;
}
a:active {
  star: expression(this.onFocus=this.blur());
}
a,
input,
button {
  outline: none;
}
button::-moz-focus-inner {
  border: 0px;
}
input::-moz-focus-inner {
  border: 0px;
}
.autowrap {
  word-wrap: break-word;
  word-break: break-all;
}
.compatible-contianer {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  min-width: 800px;
  height: 30px;
  line-height: 30px;
  background: url(/static/img/iebg.gif) repeat-x;
  z-index: 999999;
}
.cpt-ct {
  color: #363636;
  font-size: 12px;
  text-align: center;
}
.cpt-ct i {
  display: inline-block;
  width: 12px;
  height: 14px;
  vertical-align: -2px;
  margin-right: 5px;
  background: url(/static/img/iefixed-sprite.png) no-repeat 0 0;
}
.cpt-ct a {
  color: #39b94e;
}
.cpt-ct a:hover {
  text-decoration: underline;
}
.cpt-handle {
  position: absolute;
  right: 20px;
  top: 0;
  font-size: 12px;
  line-height: 27px;
}
.cpt-handle a {
  display: inline-block;
  vertical-align: middle;
}
.cpt-handle .cpt-agin {
  color: #656e73;
  margin-right: 5px;
}
.cpt-handle .cpt-agin:hover {
  color: #363d40;
}
.cpt-close {
  width: 16px;
  height: 16px;
  text-align: center;
  line-height: 16px;
  border-radius: 50%;
  transition: 0.3s;
}
.cpt-close:hover {
  background-color: #fc8800;
}
.cpt-close i {
  display: inline-block;
  height: 8px;
  width: 8px;
  vertical-align: 1px;
  background: url(/static/img/iefixed-sprite.png) no-repeat 0 -24px;
}
.cpt-close:hover i {
  background-position: 0 -42px;
}
/*用户卡片样式*/
.layer-usercard {
  position: absolute;
  z-index: 999;
  width: 370px;
  height: 165px;
  background: #fff;
  box-shadow: 0 2px 2px #999;
}
.layer-usercard .arrow {
  position: absolute;
  left: 65px;
  top: -11px;
  width: 19px;
  height: 11px;
  background: url(/static/img/dot_usercard.png);
}
.layer-usercard-header {
  height: 110px;
  background: #2a2c2e;
}
.layer-usercard-header .avatar img {
  border-radius: 50px;
  left: 21px;
  position: absolute;
  top: 21px;
  border: 3px solid #7f8082;
}
.layer-usercard-header dt,
.layer-usercard-header dd {
  float: right;
  width: 245px;
  padding-right: 20px;
  color: #fff;
}
.layer-usercard-header dt {
  padding-top: 20px;
  font-size: 18px;
}
.layer-usercard-header dd {
  font-size: 12px;
}
.layer-usercard-info ul {
  overflow: hidden;
  padding-top: 16px;
  height: 32px;
  font-size: 16px;
  color: #364247;
  position: relative;
}
.layer-usercard-info li {
  float: left;
  padding: 0 22px;
  border-right: 1px solid #d9d9d9;
}
.layer-usercard-info span {
  color: #969b9e;
  font-size: 12px;
}
.layer-usercard-info li.noborder {
  border: 0;
}
li.layer-usercard-medal {
  padding: 0;
  top: 12px;
  right: 10px;
  width: 117px;
  position: absolute;
  border: 0;
}
.layer-usercard-medal a {
  width: 32px;
  height: 32px;
  float: left;
  margin-right: 5px;
  border-radius: 1px;
  overflow: hidden;
}
.ipt {
  color: #14191e;
  background-color: #ffffff;
  border: 1px solid #98a1a6;
  height: 20px;
  padding: 9px 9px;
  font-size: 14px;
  line-height: 20px;
  border-radius: 0;
  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  -moz-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  border-color: #98a1a6;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
select.ipt {
  height: 20px;
  line-height: 20px;
}
textarea.ipt,
select[multiple].ipt {
  height: auto;
}
.ipt:-moz-placeholder {
  color: #c8cdd2;
}
.ipt::-moz-placeholder {
  color: #c8cdd2;
  opacity: 1;
}
.ipt:-ms-input-placeholder {
  color: #c8cdd2;
}
.ipt::-webkit-input-placeholder {
  color: #c8cdd2;
}
.ipt.placeholder {
  color: #c8cdd2;
}
.ipt:focus {
  border-color: #000000;
  outline: 0;
  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, 0.4);
  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, 0.4);
  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, 0.4);
}
.ipt[disabled],
.ipt[readonly],
.ipt.disabled {
  cursor: default;
  background-color: #edf1f2;
  opacity: 1;
}
textarea.ipt {
  height: auto;
}
.ipt-error {
  color: #cc0000;
  border-color: #cc0000;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.ipt-error:focus {
  border-color: #cc0000;
  outline: 0;
  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(204, 0, 0, 0.4);
  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(204, 0, 0, 0.4);
  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(204, 0, 0, 0.4);
}
.btn {
  display: inline-block;
  margin-bottom: 0;
  font-weight: 200;
  text-align: center;
  vertical-align: middle;
  touch-action: manipulation;
  cursor: pointer;
  text-decoration: none;
  box-sizing: content-box;
  background-image: none;
  border: 1px solid transparent;
  -webkit-appearance: none;
  white-space: nowrap;
  outline: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.btn:hover,
.btn:focus,
.btn.focus {
  color: #fff;
  text-decoration: none;
}
.btn:active,
.btn.active {
  outline: 0;
  background-image: none;
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
  pointer-events: none;
  opacity: 0.65;
  filter: alpha(opacity=65);
  box-shadow: none;
}
.btn-red {
  color: #ffffff;
  background-color: #cc0000;
  border-color: #cc0000;
  border-style: solid;
  border-width: 1px;
  cursor: pointer;
  -weibkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
  width: 138px;
  height: 38px;
  line-height: 38px;
  font-size: 14px;
}
.btn-red:link,
.btn-red:visited {
  color: #ffffff;
}
.btn-red:hover,
.btn-red:focus,
.btn-red.focus {
  color: #ffffff;
  background-color: #f00000;
  border-color: #f00000;
}
.btn-red:active,
.btn-red.active {
  background-color: #b30000;
  border-color: #b30000;
}
.btn-red.disabled,
.btn-red[disabled],
.btn-red.disabled:hover,
.btn-red[disabled]:hover,
.btn-red.disabled:focus,
.btn-red[disabled]:focus,
.btn-red.disabled.focus,
.btn-red[disabled].focus,
.btn-red.disabled:active,
.btn-red[disabled]:active,
.btn-red.disabled.active,
.btn-red[disabled].active {
  cursor: default;
  box-shadow: none;
  background-color: #cc0000;
  border-color: #cc0000;
}
.btn-blue {
  color: #ffffff;
  background-color: #0088cc;
  border-color: #0088cc;
  border-style: solid;
  border-width: 1px;
  cursor: pointer;
  -weibkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
  width: 138px;
  height: 38px;
  line-height: 38px;
  font-size: 14px;
}
.btn-blue:link,
.btn-blue:visited {
  color: #ffffff;
}
.btn-blue:hover,
.btn-blue:focus,
.btn-blue.focus {
  color: #ffffff;
  background-color: #00a0f0;
  border-color: #00a0f0;
}
.btn-blue:active,
.btn-blue.active {
  background-color: #0077b3;
  border-color: #0077b3;
}
.btn-blue.disabled,
.btn-blue[disabled],
.btn-blue.disabled:hover,
.btn-blue[disabled]:hover,
.btn-blue.disabled:focus,
.btn-blue[disabled]:focus,
.btn-blue.disabled.focus,
.btn-blue[disabled].focus,
.btn-blue.disabled:active,
.btn-blue[disabled]:active,
.btn-blue.disabled.active,
.btn-blue[disabled].active {
  cursor: default;
  box-shadow: none;
  background-color: #0088cc;
  border-color: #0088cc;
}
.btn-green {
  color: #ffffff;
  background-color: #00b33b;
  border-color: #00b33b;
  border-style: solid;
  border-width: 1px;
  cursor: pointer;
  -weibkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
  width: 138px;
  height: 38px;
  line-height: 38px;
  font-size: 14px;
}
.btn-green:link,
.btn-green:visited {
  color: #ffffff;
}
.btn-green:hover,
.btn-green:focus,
.btn-green.focus {
  color: #ffffff;
  background-color: #00d747;
  border-color: #00d747;
}
.btn-green:active,
.btn-green.active {
  background-color: #009a33;
  border-color: #009a33;
}
.btn-green.disabled,
.btn-green[disabled],
.btn-green.disabled:hover,
.btn-green[disabled]:hover,
.btn-green.disabled:focus,
.btn-green[disabled]:focus,
.btn-green.disabled.focus,
.btn-green[disabled].focus,
.btn-green.disabled:active,
.btn-green[disabled]:active,
.btn-green.disabled.active,
.btn-green[disabled].active {
  cursor: default;
  box-shadow: none;
  background-color: #00b33b;
  border-color: #00b33b;
}
.btn-normal {
  color: #787d82;
  background-color: #ffffff;
  border-color: #d0d6d9;
  border-style: solid;
  border-width: 1px;
  cursor: pointer;
  -weibkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
  width: 138px;
  height: 38px;
  line-height: 38px;
  font-size: 14px;
}
.btn-normal:link,
.btn-normal:visited {
  color: #787d82;
}
.btn-normal:hover,
.btn-normal:focus,
.btn-normal.focus {
  color: #787d82;
  background-color: #edf1f2;
  border-color: #98a1a6;
}
.btn-normal:active,
.btn-normal.active {
  background-color: #f2f2f2;
  border-color: #c2cace;
}
.btn-normal.disabled,
.btn-normal[disabled],
.btn-normal.disabled:hover,
.btn-normal[disabled]:hover,
.btn-normal.disabled:focus,
.btn-normal[disabled]:focus,
.btn-normal.disabled.focus,
.btn-normal[disabled].focus,
.btn-normal.disabled:active,
.btn-normal[disabled]:active,
.btn-normal.disabled.active,
.btn-normal[disabled].active {
  cursor: default;
  box-shadow: none;
  background-color: #ffffff;
  border-color: #d0d6d9;
}
.btn-sm {
  width: 78px;
  height: 28px;
  line-height: 28px;
  font-size: 12px;
}
/*发问题匹配问答关键词*/
.send-area-result {
  background: #fff;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
  -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
  -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
  position: absolute;
  top: 41px;
  left: 0;
  width: inherit;
}
.send-area-result dt {
  font-size: 12px;
  color: #c8cdd2;
  line-height: 40px;
  height: 40px;
  padding: 0 10px;
}
.send-area-result dd {
  height: 40px;
  line-height: 40px;
}
.send-area-result dd a.questiontitle {
  border: none;
  font-size: 14px;
  color: #787d82;
  width: inherit;
  text-align: left;
  height: 40px;
  line-height: 40px;
  padding: 0 10px;
  display: block;
}
.oncurr {
  color: #14191e;
  background: #edf1f2;
}
.send-area-result dd a.questiontitle i,
.send-area-result dd a.questiontitle em {
  font-style: normal;
  font-size: 12px;
  margin-left: 10px;
}
.send-area-result dd a.questiontitle em {
  color: #c8cdd2;
}
.send-area-result dd a.questiontitle i {
  color: #00b33b;
}
@font-face {
  font-family: 'icomoon';
  src: url('/static/fonts/icomoon.eot?w72hig');
  src: url('/static/fonts/icomoon.eot?#iefixw72hig') format('embedded-opentype'), url('/static/fonts/icomoon.woff?w72hig') format('woff'), url('/static/fonts/icomoon.ttf?w72hig') format('truetype'), url('/static/fonts/icomoon.svg?w72hig#icomoon') format('svg');
  font-weight: normal;
  font-style: normal;
}
[class^="icon-"],
[class*=" icon-"] {
  font-family: 'icomoon';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-stroke-width: 0.2px;
}
.icon-tick:before {
  content: "\e600";
}
.icon-home:before {
  content: "\e601";
}
.icon-clock:before {
  content: "\e602";
}
.icon-chat:before {
  content: "\e603";
}
.icon-msg:before {
  content: "\e604";
}
.icon-resp:before {
  content: "\e605";
}
.icon-addques:before {
  content: "\e606";
}
.icon-user:before {
  content: "\e607";
}
.icon-wiki:before {
  content: "\e608";
}
.icon-plan:before {
  content: "\e609";
}
.icon-note:before {
  content: "\e60a";
}
.icon-edit:before {
  content: "\e60b";
}
.icon-share:before {
  content: "\e60c";
}
.icon-set:before {
  content: "\e60d";
}
.icon-camera:before {
  content: "\e60e";
}
.icon-del:before {
  content: "\e60f";
}
.icon-search:before {
  content: "\e610";
}
.icon-key:before {
  content: "\e611";
}
.icon-mail:before {
  content: "\e612";
}
.icon-smail:before {
  content: "\e613";
}
.icon-point:before {
  content: "\e614";
}
.icon-ques:before {
  content: "\e615";
}
.icon-tick2:before {
  content: "\e616";
}
.icon-chapter:before {
  content: "\e617";
}
.icon-mobile:before {
  content: "\e618";
}
.icon-gotop:before {
  content: "\e619";
}
.icon-statistic:before {
  content: "\e61a";
}
.icon-code:before {
  content: "\e61b";
}
.icon-video:before {
  content: "\e61c";
}
.icon-test:before {
  content: "\e61d";
}
.icon-menu:before {
  content: "\e61e";
}
.icon-plus:before {
  content: "\e61f";
}
.icon-sub:before {
  content: "\e620";
}
.icon-close:before {
  content: "\e621";
}
.icon-down:before {
  content: "\e622";
}
.icon-left:before {
  content: "\e623";
}
.icon-top:before {
  content: "\e624";
}
.icon-right:before {
  content: "\e625";
}
.icon-exit:before {
  content: "\e626";
}
.icon-refresh:before {
  content: "\e627";
}
.icon-again:before {
  content: "\e628";
}
.icon-bell:before {
  content: "\e629";
}
.icon-nobell:before {
  content: "\e62a";
}
.icon-nolearn:before {
  content: "\e62b";
}
.icon-half:before {
  content: "\e62c";
}
.icon-full:before {
  content: "\e62d";
}
.icon-point-revert:before {
  content: "\e62e";
}
.icon-ques-revert:before {
  content: "\e62f";
}
.icon-tick-revert:before {
  content: "\e630";
}
.icon-flag:before {
  content: "\e631";
}
.icon-msg-revert:before {
  content: "\e632";
}
.icon-ad:before {
  content: "\e633";
}
.icon-imooc:before {
  content: "\e634";
}
.icon-thumb:before {
  content: "\e635";
}
.icon-thumb-revert:before {
  content: "\e636";
}
.icon-star:before {
  content: "\e637";
}
.icon-star-revert:before {
  content: "\e638";
}
.icon-heart:before {
  content: "\e639";
}
.icon-heart-revert:before {
  content: "\e63a";
}
.icon-qq:before {
  content: "\e63b";
}
.icon-weibo:before {
  content: "\e63c";
}
.icon-qqweibo:before {
  content: "\e63d";
}
.icon-weixin:before {
  content: "\e63e";
}
.icon-folder:before {
  content: "\e63f";
}
.icon-jian:before {
  content: "\e640";
}
.icon-ding:before {
  content: "\e641";
}
.icon-you:before {
  content: "\e642";
}
.icon-apple:before {
  content: "\e643";
}
.icon-android:before {
  content: "\e644";
}
/*course_intrduce*/
.gotoTopBtn{
    margin-left: 615px;
}
body{
    background:#EEEFF1

}

.course_info {
    display: inline-block;
    height:340px;
    overflow:hidden;
    margin-top:10px;
}
.container h2 {
    height: 60px;
    color: #5e5e5e;
    font-size: 24px;
    clear: both;
}
.course-embed{
    position: relative;
}
.video-btn:link,
.video-btn:visited{
    background: url(../img/course_info_sprit.png) no-repeat 25px -32px #c9394a;
    opacity: 0.8;
    filter:alpha(opacity=80);
    position: absolute;
    top: 145px;
    left: 35%;
    font-size: 24px;
    text-align: center;
    border:5px solid #fff;
    border-radius:30px;
    padding:0 30px 0 60px;
    height:50px;
    line-height:50px;
    color: #fff;
}
.video-btn:hover{
    opacity:0.9;
    filter:alpha(opacity=90);
}
.course_video {
    width: 600px;
    height:340px;
    overflow: hidden;
}

#VideoCover {
    position: relative;
}
#course_front {
    background: url(../img/course_info_sprit.png) no-repeat 18px -29px #c9394a;
    opacity: 0.8;
    filter:alpha(opacity=80);
    position: absolute;
    top: 145px;
    left: 35%;
    color: #fff;
    font-size: 24px;
    text-align: center;
    border:5px solid #fff;
    border-radius:30px;
    padding:0 20px 0 50px;
    height:52px;
    line-height:52px
}
#course_front:hover{
    opacity:0.9;
    filter:alpha(opacity=90);
}

#course_intro .video {
    position: relative;
    background: #fff;
    width: 600px;
    height: 340px;
}
.course_state {
    width:240px;
    float: left;
    background: #364247;
    padding:0 40px;
    height: 340px;
    overflow: hidden;
}
.course_state ul li {
    height: 113px;
    border-bottom: 1px solid #414f55;
    overflow:hidden;
    line-height: 113px;
}
.course_state ul li.mr {
    margin-right: 10px;
}
.course_state ul li span {
    color: #909b9e;
    font-size: 14px;
    line-height: 24px;
    margin-right:15px;
}
.course_state ul li em,.course_hour .ft-adjust span{
    font-size: 24px;
    color: #ffffff;
}
.course_hour .ft-adjust{
    font-size:14px;
}
.course_hour .ft-adjust span{
    display:inline;
    margin:0;
}
.course_state ul li.course_hour {
    position: relative;
}
.course_state ul li i {
    padding:0 3px;
    background: #e5e5e5;
    text-align: center;
    color: #5e5e5e;
    position: absolute;
    right: 0;
    bottom: 0;
    font-style: normal;
    font-size: 16px;
}
.concerned_course{
    background:#4d5a61;
}
.concerned_course em{
    text-align: center;
    display: block;
}

.concerned_course .btn-add-follow {
    display: block;
    height: 100px;
    padding-top:40px;
    text-align: center;
}
.btn-add-follow i{
    display: inline-block;
    background: url(/static/img/course/new_add_collection.png) no-repeat 0 0;
    width: 36px;
    height:32px;
    color:#909b9e;
    text-align: center;
}
.btn-add-follow em{
    display: block;
    color: #909b9e;
    line-height: 1em;
}
.btn-add-follow:hover i{
    background-position: 0 -44px
}
.btn-add-follow:hover em{
    color: #fff;
}
.btn-remove-follow i{
    background-position: 0 -88px;
}
.btn-remove-follow:hover i{
    background-position: 0 -130px;
}


.curse_btn button.unopencourse{
    background:#5e5e5e;
    cursor: default;
}
.curse_btn {
    clear: both;
}
.curse_btn button,.curse_btn a{
   height:200px;
   width:100%;
   background:#c9394a;
   text-align:center;
   color:#fff;
   font-size:24px;
   line-height:200px;
   cursor:pointer;
   display:block;
   overflow: hidden;
}
.curse_btn a:hover{
    background: #d65c5c;
}
/*边栏教师信息*/

.course_teacher {
    padding-top: 10px;
}

.course_teacher h3{
    margin-top:15px;
    font-size: 16px;
    color:#333;
}
.course_teacher dl {
    float: right;
    padding: 5px 10px 5px 5px;
    width: 765px;
}
.course_teacher dl dt {
    color: #5E5E5E;
    font-size: 24px;
    line-height: 36px;
}
.course_teacher .teacher_icon {
    background: url("../img/qadetailicon.png") no-repeat scroll 0 -97px ;
    display:inline-block;
    height:16px;
    margin-left: 10px;
    width:16px;
    margin-top:3px
}
.course_teacher dl dt span.teacher_iden {
    background: url("../img/curse_icon.png") no-repeat scroll -43px 0;
    display: none;
    height: 16px;
    margin-left: 5px;
    width: 60px;
}
.course_teacher dl dt span.idec_show {
    display: inline-block;
}
.course_teacher dl dd {
    color: #666565;
    font-size: 14px;
    line-height: 24px;
}
.course_teacher a.teacer_pic {
    float: left;
    margin-right: 10px;
}
.course_teacher .teacer_pic img{
    border-radius: 40px;
    -moz-border-radius: 40px;
    -webkit-border-radius: 40px;
    -ms-border-radius: 40px;
    -o-border-radius: 40px

    }
.course_teacher p{
    font-size: 12px;
    word-wrap: break-word;
    color: #666;
}

.course_teacher .discrip{

    margin-bottom:20px;
    font-size:12px

    }
/*边栏教师信息end*/
.chapter_introduces,.chapter_catalog{
    color:#303538;
    font-size:18px;
    line-height:40px;
    height: 40px;
}
.chapter_catalog{
    margin-top: 20px;
}
.course_shortdecription{
    color:#60686b;
    font-size:14px;
    line-height: 30px;
    word-break:break-all;
    white-space:normal
}
/*outline*/
.course_list{
    clear:both;
    display:inline-block;
    width:100%;
    margin-top:12px;
}
.outline{
    width:840px;
    float:left;
    padding:40px 40px 0 40px;
    min-height:800px;
    background: #fff;
    -webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    -moz-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.outline ul {
    margin:5px 0 0 0;
}
.outline li {
    position: relative;
    overflow: hidden;
    padding:15px 0;
    z-index:2;
    vertical-align:middle;
}
.outline_list{
    position: relative;
    margin-left:10px;
    padding:5px 0;
    width:775px
}
em.outline_zt{
   background:url(../img/curse_icon.png) no-repeat 0 -264px;
   width:10px;
   height:15px;
   display:none;
   position:absolute;
   left:-6px;
   top:15px;
}
.outline_name{
    color:#60686b;
    font-size:18px;
}
.unopen .outline_name{
    color:#99a1a6;
    font-size: 18px;
}
.unopen .outline_descr{
    color:#99a1a6;
    font-size: 12px;
}
.outline_descr {
    color:#60686b;
    font-size:12px;
    line-height: 24px;
}
.outline_listH{
    background:#efefef;
}

.course_right{
   float:right;
   width:260px;
}
.course_right dl{
   clear:both;
   padding:0 20px;
   background: #fff;
   margin-bottom: 20px;
   -webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
   -moz-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
   box-shadow: 0 2px 4px rgba(0,0,0,0.1);

}
.course_right dl dt{
    border-bottom: 1px solid #d0d6d9;
    font-size: 16px;
    height:50px;
    line-height: 50px
}
.course_right dl dd{
   color:#656e73;
   font-size:12px;
   line-height:2em;
   word-break:break-all;
   white-space:normal;
   padding:10px 0;
}
.course_right .wrd_break{
    white-space: pre-wrap;
    white-space: -moz-pre-wrap;
    white-space: -pre-wrap;
    white-space: -o-pre-wrap;
    word-wrap: break-word;
    font-family:Microsoft YaHei,​SimSun,​Arial;
    font-size:12px;
}

a.back-btn{
    width:60px;
    height: 60px;
    font-size: 36px;
    display:block;
    float:left;
    text-align: center;
}
a.back-btn:hover{
    background: #cc3333;
    color:#fff;
}
.course-title{
    height:60px;
    line-height: 60px;
    overflow:hidden;
    color:#364247;
}
.course-title h2,.course-title h1{
    float:left;
    padding-left:10px;
    font-size:22px;
    color: #333;
}
.course_intro{
    float:right;
    width:280px;
    background: #4d5a61;
}

.course_description{
    height: 200px;
    line-height: 1.63;
    overflow: hidden;
    padding:10px 20px;
}
.course_notes{
    border-bottom:1px solid #4d5559;
    color:#b4bbbf;
    padding:10px 20px;
}
.openicon{
    float:left;
    width:41px;
    height:41px;
    display:block;
    margin:5px 0 0 10px;
    background: url(../img/course_info_sprit.png) no-repeat 0 -106px;

}
.unopenicon{
    float:left;
    width:41px;
    height:41px;
    display:block;
    margin:5px 0 0 10px;
    background: url(../img/course_info_sprit.png) no-repeat 0 -227px;

}
#couList li a:hover h5{
    color:#be3948;
    text-decoration:underline
}

#couList li a:hover .openicon{
    background: url(../img/course_info_sprit.png) no-repeat 0 -148px;
}
.path{
    font-size:16px;
     color:#787d80;
}
.path span{
    color:#364247;
}
.path a{
    color:#787d80;
}
  • \spring-mvc-study-master\src\main\webapp\WEB-INF\jsps\course_admin\edit.jsp
<%@ page language="java" 
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>我不是真正的慕课网</title>

<link rel="stylesheet"
    href="<%=request.getContextPath()%>/resources/css/main.css"
    type="text/css" />
</head>
<body>
    <div id="main">
        <div class="newcontainer" id="course_intro">
          <form name="mainForm" action="<%= request.getContextPath()%>/courses/save" method="post">
            <div>
               <span>课程名称:</span><input type="text" id="title" name="title">
            </div>
            <div>
               <span>课程时长:</span><input type="text" id="duration" name="duration"></div> 
            <div>
               <span>课程难度:</span>
               <select id="level" name="level">
                  <option value="0">初级</option>
                  <option value="1" selected="selected">中级</option>
                  <option value="2">高级</option>
                </select>
            </div> 
            <div>
               <span>课程介绍:</span>
               <textarea id="descr" name="descr" rows="5" style="width:480px"></textarea>
            </div> 
            <div>
               <input type="submit" id="btnPass" value="提交" />
            </div> 
          </form>
        </div>
    </div>
</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\WEB-INF\jsps\course_admin\file.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>我不是真正的慕课网</title>

<link rel="stylesheet" href="<%=request.getContextPath()%>/resources/css/main.css" type="text/css" />
</head>
<body>
<div align="center">

<h1>上传附件</h1>
<form method="post" action="/courses/doUpload" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit"/>
</form>
</div>
</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\WEB-INF\jsps\course_admin\multifile.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>我不是真正的慕课网</title>

<link rel="stylesheet" href="<%=request.getContextPath()%>/resources/css/main.css" type="text/css" />
</head>
<body>
<div align="center">
<h1>上传多个附件</h1>
<form method="post" action="/courses/doUpload2" enctype="multipart/form-data">
<input type="file" name="file1"/>
<br/>
<input type="file" name="file2"/>
<input type="submit"/>
</form>

</div>
</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\WEB-INF\jsps\course_overview.jsp
<%@ page language="java" 
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>我不是真正的慕课网</title>

<link rel="stylesheet"
    href="<%=request.getContextPath()%>/resources/css/main.css"
    type="text/css" />
</head>
<body>


    <div id="main">

        <div class="newcontainer" id="course_intro">
            <div class="course-title">${course.title}</div>
            <div class="course_info">
                <div class="course-embed l">
                    <div id="js-course-img" class="img-wrap">
                        <img width="600" height="340" alt=""
                            src="<%=request.getContextPath()%>/${course.imgPath}"
                            class="course_video" />
                    </div>
                    <div id="js-video-wrap" class="video" style="display: none">
                        <div class="video_box" id="js-video"></div>
                    </div>
                </div>
                <div class="course_state">
                    <ul>
                        <li><span>学习人数</span> <em>${course.learningNum }</em></li>
                        <li class="course_hour"><span>课程时长</span> <em
                            class="ft-adjust"><span>${course.duration }</span></em></li>
                        <li><span>课程难度</span> <em>${course.levelDesc }</em></li>
                    </ul>
                </div>
<!--  
                <div class="course_intro">
                    <div class="concerned_course add_concerned_course">
                        <a href="javascript:void(0)" data-id="202"
                            class="btn-add-follow js-btn-follow"> <i></i> <em
                            class="concerned-icon">关注此课程</em>
                        </a>
                    </div>
                    <div class="curse_btn">
                        <a href="#">开始学习</a>
                    </div>
                </div>
    -->         
            </div>
            <div class="course_list">
                <div class="outline">
                    <h3 class="chapter_introduces">课程介绍</h3>
                    <div class="course_shortdecription">${course.descr}</div>

                    <h3 class="chapter_catalog">课程提纲</h3>
                    <ul id="couList">
                        <c:forEach items="${course.chapterList}" var="chapter">
                            <li class="clearfix open"><a href="#">
                                    <div class="openicon"></div>
                                    <div class="outline_list l">
                                        <!-- <em class="outline_zt"></em> -->
                                        <h5 class="outline_name">${chapter.title }</h5>
                                        <p class="outline_descr">${chapter.descr }</p>
                                    </div>
                            </a></li>
                        </c:forEach>
                    </ul>
                </div>

            </div>
        </div>

    </div>


</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\WEB-INF\jsps\home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Hello Spring MVC!
Here is iMooc!
</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\WEB-INF\jsps\success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" href="<%=request.getContextPath()%>/resources/css/main.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center">
<h1>Success</h1>
</div>
</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\course_json.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>我不是真正的慕课网</title>

<link rel="stylesheet"
    href="<%=request.getContextPath()%>/resources/css/main.css"
    type="text/css" />
<script type="text/javascript"
    src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

</head>
<script>
jQuery(function($){
    var urlStr = "<%=request.getContextPath()%>/courses/<%=request.getParameter("courseId")%>";
    //alert("Before Call:"+urlStr);
    $.ajax({
        method: "GET",
        url: urlStr,
        success:function(data,status,jqXHR){
            //alert("Success:"+data);
            var course = data;
            var path = "<%=request.getContextPath()%>/";    
            $(".course-title").html(course.title);
            $(".course_video").attr("src", path+course.imgPath);
            $("#learningNum").text(course.learningNum);
            $("#duration").text(course.duration);
            $("#levelDesc").text(course.levelDesc);
            $(".course_shortdecription").html(course.descr);

            var chapterList = course.chapterList;
            var chapter;

            for(var i = 0;i<chapterList.length;i++){
                chapter = chapterList[i];   

                var liObj = $("li",$("#chapterTemplate")).clone();              
                $(".outline_name", liObj).text(chapter.title);
                $(".outline_descr", liObj).text(chapter.descr);                
                liObj.appendTo("#couList");             
            }// ~ end for          
        }
    }); // end ajax
});
</script>
<body>


    <div id="main">

        <div class="newcontainer" id="course_intro">
            <div class="course-title"></div>
            <div class="course_info">
                <div class="course-embed l">
                    <div id="js-course-img" class="img-wrap">
                        <img width="600" height="340" alt=""
                            class="course_video" />
                    </div>
                    <div id="js-video-wrap" class="video" style="display: none">
                        <div class="video_box" id="js-video"></div>
                    </div>
                </div>
                <div class="course_state">
                    <ul>
                        <li><span>学习人数</span> <em id="learningNum"></em></li>
                        <li class="course_hour"><span>课程时长</span> <em
                            class="ft-adjust"><span id="duration"></span></em></li>
                        <li><span>课程难度</span> <em id="levelDesc"></em></li>
                    </ul>
                </div>

            </div>
            <div class="course_list">
                <div class="outline">
                    <h3 class="chapter_introduces">课程介绍</h3>
                    <div class="course_shortdecription"></div>

                    <h3 class="chapter_catalog">课程提纲</h3>
                    <ul id="couList">

                    </ul>
                </div>

            </div>
        </div>

    </div>

    <div id="chapterTemplate"  style="display:none">
       <li class="clearfix open"><a href="#">
                <div class="openicon"></div>
                <div class="outline_list l">
                        <h5 class="outline_name"></h5>
                        <p class="outline_descr"></p>
                </div>
         </a></li>
    </div>

</body>
</html>
  • \spring-mvc-study-master\src\main\webapp\index.jsp
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

Spring Framework 参考手册
代码示例

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值