上一篇已经大致讲了该项目的前台展示界面和管理的一些内容:
具体链接如下:
基于SSM的网上商城(中)
这篇来讲讲该项目的一些细节以及所用到的一些知识点
一、该项目是基于SSM框架以及EasyUI的前端框架设计
SSM框架:spring、springMVC、mybaits。
Spring:是一个容器。类似与一个对象工厂,按要求标记的类都会被提前放入这个容器。
SpringMVC:控制器和视图分发器。
Mybaits:jdbc封装,本质就是jdbc对数据库的操作。Sqlsessionfactory实例,其中实体、数据库表、mapper三者一一对应,缺一不可。
根据用户写的实体类和映射mapper文件之间的对应来获取到相应的sql操作去执行。
1.spring配置文件
- 首先是在applicationContext.xml文件里面进行配置项目的扫描器。
<context:component-scan base-package="com.xieyunjie.programmer">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Component" />
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Repository" />
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>
- 加载配置数据源的配置文件 db.properties
<context:property-placeholder location="classpath:config/db.properties" />
- 配置数据库的c3p0数据源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
- 配置事务管理器
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 获取sqlSessionFactory工厂类
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- 配置扫描dao层,动态实现dao层接口,注入到spring容器中
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xieyunjie.programmer.dao" />
<!-- 注意使用 sqlSessionFactoryBeanName 避免出现spring 扫描组件失效问题 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
2.配置springmvc配置文件
- 扫描包中的Controller注解
- 配置视图解析器
- 配置文件上传控制器
- 后台访问拦截器
对于个格文件里面的注解的解释
一、Controller类
- @RequestMapping()
1.@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。
2.在 Spring MVC 应用程序中,RequestDispatcher (在 Front Controller 之下) 这个 servlet 负责将进入的 HTTP 请求路由到控制器的处理方法。
在对 Spring MVC 进行的配置的时候, 你需要指定请求与处理方法之间的映射关系。
3.要配置 Web 请求的映射,就需要你用上 @RequestMapping 注解。
@RequestMapping 注解可以在控制器类的级别和/或其中的方法的级别上使用。
4.在类的级别上的注解会将一个特定请求或者请求模式映射到一个控制器之上。之后你还可以另外添加方法级别的注解来进一步指定到处理方法的映射关系。*
如上述代码所示,到/admin/log的请求由下面的方法进行处理,比如到/home/index的请求会由list方法来处理,并且使用的get方法进行处理。
@RequestMapping 来处理多个 URI
你可以将多个请求映射到一个方法上去,只需要添加一个带有请求路径值列表的 @RequestMapping 注解就行了。
- @Controller
1.以前在编写Controller方法的时候,需要开发者自定义一个Controller类实现Controller接口,实现handleRequest方法返回ModelAndView。并且需要在Spring配置文件中配置Handle,将某个接口与自定义Controller类做映射。
这么做有个复杂的地方在于,一个自定义的Controller类智能处理一个单一请求。而在采用@Contoller注解的方式,可以使接口的定义更加简单,将@Controller标记在某个类上,配合@RequestMapping注解,可以在一个类中定义多个接口,这样使用起来更加灵活。
被@Controller标记的类实际上就是个SpringMVC Controller对象,它是一个控制器类,而@Contoller注解在org.springframework.stereotype包下。其中被@RequestMapping标记的方法会被分发处理器扫描识别,将不同的请求分发到对应的接口上。
这里提一点,Spring如何通过注解注入?
不过大家仔细想一下,为什么打上注解了就能实现接口功能了呢?换句话说,Spring怎么样找到开发者自定义的Controller把对应的请求分发到对应的方法上呢?
首先,要在Spring配置文件的头文件中引入spring-context。
其次,使用context:component-scan元素启动“包扫描”功能。
例如<context:component-scan base-package=“com.myz.controller”/>
base-package是值是包的路径。意思就是,启动了报扫描功能,将com.myz.controller这个包下以及子包下的所有类扫描一遍,将标记有@Controller、@Service、@repository、@Component等注解的类注入到IOC容器中,作为Spring的Bean来管理。
这样,Spring就能找到Controller类,通过@RequestMapping注解处理对应的请求。
- @Autowrited
1.组或集合的注入
Spring容器中所有了类型匹配的bean都被注入进来,并且如果bean有@Order注解或者实现Order接口,按照Order的先后顺序注入;
Map的注入
key的类型必须为String,注入后值为bean的名称;
value类型即为想要注入的bean类,所有类型匹配的bean会被注入进来;
2.注解解析器:AutowiredAnnotationBeanPostProcessor
Spring容器启动时,AutowiredAnnotationBeanPostProcessor被注册到容器;
扫描代码,如果带有@Autowired注解,则将依赖注入信息封装到InjectionMetadata中(见扫描过程);
创建bean时(实例化对象和初始化),会调用各种BeanPostProcessor对bean初始化,AutowiredAnnotationBeanPostProcessor负责将相关的依赖注入进来;
3.@Autowired扫描过程
扫描当前类中标注@Autowired的属性和方法;
再查找父类中注@Autowired的属性和方法,依次遍历;
- @RequestParam
1.@RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
2.语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
value:参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
3.@RequestParam 注解配合 @RequestMapping 一起使用,可以将请求的参数同处理方法的参数绑定在一起。
@RequestParam 注解使用的时候可以有一个值,也可以没有值。这个值指定了需要被映射到处理方法参数的请求参数,
- @ResponseBody
1.responseBody一般是作用在方法上的,加上该注解表示该方法的返回结果直接写到Http response Body中,常用在ajax异步请求中,
在RequestMapping中 return返回值默认解析为跳转路径,如果你此时想让Controller返回一个字符串或者对象到前台 就会报404 not response的错误。
当加上@ResponseBody注解后不会解析成跳转地址 会解析成相应的json格式的对象 集合 字符串或者xml等直接返回给前台 可以通过 ajax 的“success”:fucntion(data){} data直接获取到。
2.注册验证: 希望返回给前台 一个json字符串 来表示 注册是否成功 而不是 跳转路径 所以此处 方法 加上 @ResponseBody注解 避免被解析成跳转路径
3.@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
二、dao层
1.@Repository
1.Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的开发。@Repository注解便属于最先引入的一批,它用于将数据访问层 (DAO 层 ) 的类标识为 Spring Bean。具体只需将该注解标注在 DAO类上即可。同时,为了让 Spring 能够扫描类路径中的类并识别出 @Repository 注解,需要在 XML 配置文件中启用Bean 的自动扫描功能,这可以通过context:component-scan/实现
2.为什么 @Repository 只能标注在 DAO 类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。 Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
Spring 2.5 在 @Repository的基础上增加了功能类似的额外三个注解:@Component、@Service、@Constroller,它们分别用于软件系统的不同层次:@Component 是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。@Service 通常作用在业务层,但是目前该功能与 @Component 相同。@Constroller 通常作用在控制层,但是目前该功能与 @Component 相同。
三、entity类
@Component
1.(把普通pojo实例化到spring容器中,相当于配置文件中的)
@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。
2.@Component是一个元注解,意思是可以注解其他类注解,如@Controller @Service @Repository @Aspect。官方的原话是:带此注解的类看为组件,当使用基于注解的配置和类路径扫描的时候,这些类就会被实例化。其他类级别的注解也可以被认定为是一种特殊类型的组件,比如@Repository @Aspect。所以,@Component可以注解其他类注解。
四、service类
@Service
1.@Service 通常作用在业务层,但是目前该功能与 @Component 相同。
2.@Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中,不需要再在applicationContext.xml文件定义bean了。
下面我们来说说前端界面的数据是怎么样与后端进行交互的
这里咱们使用到了ajax技术:
先说说什么是Ajax
Ajax(Asynchronous JavaScript and XML) 异步JavaScript和XML
Ajax实际上是下面这几种技术的融合:
(1)XHTML和CSS的基于标准的表示技术
(2)DOM进行动态显示和交互
(3)XML和XSLT进行数据交换和处理
(4)XMLHttpRequest进行异步数据检索
(5)Javascript将以上技术融合在一起
客户端与服务器,可以在【不必刷新整个浏览器】的情况下,与服务器进行异步通讯的技术 。
为什么我们需要Ajax?
在我们之前的开发,每当用户向服务器发送请求,哪怕只是需要更新一点点的局部内容,服务器都会将整个页面进行刷新。
性能会有所降低(一点内容,刷新整个页面!)
用户的操作页面会中断(整个页面被刷新了)
Ajax就是能够做到局部刷新!
回归正题!
就拿咱们的这个项目的前端的account/list.jsp来说
/**
* 添加记录
*/
function add(){
var validate = $("#add-form").form("validate");
if(!validate){
$.messager.alert("消息提醒","请检查你输入的数据!","warning");
return;
}
var data = $("#add-form").serialize();
$.ajax({
url:'add',
dataType:'json',
type:'post',
data:data,
success:function(data){
if(data.type == 'success'){
$.messager.alert('信息提示','添加成功!','info');
$('#add-dialog').dialog('close');
$('#data-datagrid').datagrid('reload');
}else{
$.messager.alert('信息提示',data.msg,'warning');
}
}
});
}
代码块里的先是一个add()添加函数,在里面有一个 $.ajax() ,这里面包含了 “url”,“dataType”,“type”,“data” ,以及成功后或者之败后对应的一个函数。
这里的url对应的就是控制器里面的一个方法。
account/list.jsp