SSM框架学习文档以及SSM整合(附Github地址=>含SSM学习时的实例代码)

SSM框架学习

软件架构:

基于流行SSM框架:Spring+SpringMVC+Mybatis

项目配置: 使用Maven进行项目jar导入

​ 使用Git进行版本控制,并将每次编写的代码上传到Gitee进行保存

环境需求:

​ IDEA(装有Web相关插件以及Maven插件和Git插件)

​ Navcat(mysql 5.7 图形化管理工具)

​ JDK 1.8

环境配置

​ IDEA中的Maven配置,Git配置,请自行查阅,网上有相关资源

参考网站:

Maven Repository : https://mvnrepository.com/

Gitee:https://gitee.com/

Gitee 项目仓库:https://gitee.com/xuzhi7162/SSM

GitHub项目仓库:https://github.com/xuzhi7162/SSM/tree/master/NewProject/JavaWebTest

(使用IntelliJ IDEA尝试开发)

Mybatis教程:https://blog.csdn.net/hellozpc/article/details/80878563#3Mybaits_109

SpringMVC文档地址(老版):https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/htmlsingle/#overview-distribution-zip

Mybatis

日志工具

##引入相关依赖


	<dependency>
      <groupId>log4jgroupId>
      <artifactId>log4jartifactId>
      <version>1.2.17version>
    dependency>

##在全局配置文件中添加相应的setting设置

<settings>
		
		<setting name="logImpl" value="LOG4J"/>
settings>

##在resources目录下建立log4j.properties配置文件,并在内部做出相应修改

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.xuzhi.mapper=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

###修改内容如下

官方语句为

log4j.logger.org.mybatis.example.BlogMapper.selectBlog=TRACE

修改为

log4j.logger.com.xuzhi.mapper=DEBUG

即将原先的org.mybatis.example.BlogMapper.selectBlog修改为你mapper所在的包,并将后面的TRACE修改为DEBUG以便于在控制台打印

mybatis-config.xml

##Mybatis的全局配置文件

 

<configuration>
	<properties>
		<property name="driver" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
		<property name="username" value="root"/>
		<property name="password" value="xuzhi7162"/>
	properties>
    <settings>
		
		<setting name="logImpl" value="LOG4J"/>
	settings>
	<environments default="mybatis">
		
		<environment id="mybatis">
			<transactionManager type="JDBC" />
			<dataSource type="UNPOOLED">
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			dataSource>
		environment>
	environments>
	
	<mappers>
		
		
		<mapper resource="com/xuzhi/mapper/UserInfoMapper.xml" />
		
		<package name="com/xuzhi/po"/>
	mappers>
configuration>

##两种mapper引入方法:直接引入配置文件,引入实体类所在的包

UserInfoMapper.xml

##UserInfoMapper实体类的配置文件,该配置文件必须在全局配置文件mybatis.cfg,xml中注册




<mapper namespace="com.xuzhi.mapper.UserInfoMapper">
	
	<insert id="insert" parameterType="com.xuzhi.po.UserInfo">
		insert into user_info(user_name,user_pass,user_phone) values(#{userName},#		{userPass},#{userPhone})
	insert>
mapper>

##对相应数据表的GRUD操作的语句都写于该配置文件中,

#{}和${}

#{} 只是替换?,相当于PreparedStatement使用占位符去替换参数,可以防止sql注入。
是 进 行 字 符 串 拼 接 , 相 当 于 s q l 语 句 中 的 S t a t e m e n t , 使 用 字 符 串 去 拼 接 s q l ; {} 是进行字符串拼接,相当于sql语句中的Statement,使用字符串去拼接sql; sqlStatement使sql可以是sql中的任一部分传入到Statement中,不能防止sql注入。

注:所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

MybatisUtil.java工具类

##用与返回SqlSession

package com.xuzhi.util;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 *  单例类,在程序中仅有一个类
 * @author 绪志
 *
 */
public class MybatisUtil {
	 private static SqlSessionFactory sqlSessionFactory;
	 /**
	   *   静态代码块,在程序的所有运行过程中,该代码块仅执行一次,类似于单例
	  */
	    static {
	    	//指定全局配置文件
	        String resource="mybatis.cfg.xml";
	        InputStream in=null;
	        try {
	        	//读取配置文件
	            in = Resources.getResourceAsStream(resource);
	            //构建SqlSessionFactory
	            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
	        } catch (IOException e) {
	            e.printStackTrace();
	        }finally {
	            if(in != null){
	                try {
	                    in.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }
	    public static SqlSession getSession(){
	    	//返回SqlSession
	        return sqlSessionFactory.openSession();
	    }
}

UserInfoMapper.java

package com.xuzhi.mapper;

import com.xuzhi.po.UserInfo;
/**
 * 该接口中主要是对UserInfo实体类的GRUD操作,不需要实现该接口,仅需要在UserInfoMapper.xml中添加相应的sql语句既可
 * @author 绪志
 *
 */
public interface UserInfoMapper {
	int insert(UserInfo userInfo);
}

SQL语句

select复合查询语句

##推荐使用注解方法 @Param()

/**
     * 通过name和flower进行复合查询,通过注解可以在mapper的配置文件中直接使用#{name}和#{flower}来接收参数
     * 否则必须使用mybatis默认的参数接收方式,param1,param2或者arg0,arg1
     * 推荐使用注解的方式来进行传递参数
     * @param name
     * @param flower
     * @return
     */
    Girl queryByNameFlower(@Param("name") String name,@Param("flower") String flower);

##通过就Javabean进行参数传递

/**
     * 通过javabean来传递参数
     * mapper.xml中调用参数时只需要使用实体类中的属性名即可
     * @param girl
     * @return
     */
    Girl queryByNameFlower1(Girl girl);

###在传入多个javabean时,在接收参数时可以使用param1.XXX,此方法是不友好的,可以在定义方法时使用@Param注解,

例:@Param(“a”) Girl girl==========使用时可以使用"a.XXX"

##通过hashmap进行参数传递(在mapper中按照键的名称取值)

/**
     * 通过hashmap传参
     * @return
     */
    Girl queryByNameFlower2(Map<String,Object> map);

动态SQL

##本部分没有做测试类,完全摘自Mybatis官方文档

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

  • bind

  • sql

if

动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。比如:

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG 
  <where> 
    <if test="state != null">
        AND state = #{state}
    if> 
    <if test="title != null">
        AND title like #{title}
    if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    if>
  where>
select>

##在使用where条件是可以使用专门的标签,从而使mybatis自动处理查询条件前面的‘and’关键字,推荐在所有的if语句中所有的查询关键字前面都加上and关键字,即使是第一个在其内容中也要加入and关键字,因为mybatis会帮我们处理好这个and关键字,例如

<where> 
    <if test="state != null">
        AND state = #{state}
    if> 
where>
choose, when, otherwise

##有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    when>
    <otherwise>
      AND featured = 1
    otherwise>
  choose>
select>
trim, where, set

标签代码同标签内的代码

标签可以看成为的自定义标签,可以通过内部的某些属性来处理AND/OR,还可以处理“,”

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
trim>

###官方文档没有完全给出标签内的所有属性,具体使用时需要具体百度

标签可以处理标签中多余的“,”,例如update中的set后项目的“,”

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},if>
      <if test="password != null">password=#{password},if>
      <if test="email != null">email=#{email},if>
      <if test="bio != null">bio=#{bio},if>
    set>
  where id=#{id}
update>

###同标签处理AND/OR一样,可以在每个语句的后面都填上“,”,标签都可以帮我们处理掉

foreach
<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list" open="(" separator="," 					close=")">
        #{item}
  foreach>
select>

​ · item:自命名,用来表示需要遍历的集合的其中的一个子项

​ ·index:当前遍历到的下标

​ ·collection:需要遍历的类型 #list、set、map

​ ·open:以什么为开始

​ ·separator:每个子项之间用什么符号分隔开

​ ·close:以什么为结尾

上述代码可“编译出”,

select * from post p where ID in (a,b,c,d)
bind

###bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
select>
sql

这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password sql>

这个 SQL 片段可以被包含在其他语句中,例如:

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/>include>,
    <include refid="userColumns"><property name="alias" value="t2"/>include>
  from some_table t1
    cross join some_table t2
select>

Mybatis关系映射

##使用mybatis处理一般的单表时常使用resultType属性,但是用mybatis处理多表查询时,使用resultType进行结果集的封装不太适用,所以此时要使用自定义封装结果集,多使用resultMap进行自定义结果集的封装

一对一关系映射

##简要说明,一对一举例,一个用户拥有自己独特的个人信息,一个用户对应一个用户详情信息

<方法一:使用assocation进行具体对象的封装>



<mapper namespace="com.xuzhi.mapper.GirlDetailMapper">

    
    
    <resultMap id="BaseGirlDetail" type="com.xuzhi.model.GirlDetail">
        <id property="id" column="uid" />
        <result property="name" column="name" />
        <result property="flower" column="flower" />
        <result property="birthday" column="birthday" />
    resultMap>

    
    <resultMap id="GirlWithDetailMap" type="com.xuzhi.model.GirlDetail">
        <id property="id" column="uid" />
        <result property="name" column="name" />
        <result property="flower" column="flower" />
        <result property="birthday" column="birthday" />
        <association property="girlWithDetail" javaType="com.xuzhi.model.GirlWithDetail">
            <id property="gid" column="gdid" />
            <result property="address" column="address" />
        association>
    resultMap>
    
    <resultMap id="GirlWithDetailMap2" type="com.xuzhi.model.GirlDetail">
        <id property="id" column="uid" />
        <result property="name" column="name" />
        <result property="flower" column="flower" />
        <result property="birthday" column="birthday" />
        
        <result property="girlWithDetail.gid" column="gdid" />
        <result property="girlWithDetail.address" column="address" />
    resultMap>

    
    <resultMap id="GirlWithDetailMap3" extends="BaseGirlDetail" type="com.xuzhi.model.GirlDetail">
        
        <association property="girlWithDetail" select="com.xuzhi.mapper.GirlWithDetailMapper.queryById" column="uid">
        association>
    resultMap>


    <select id="queryById" resultMap="GirlWithDetailMap2">
        select t1.id as uid,t1.`name`,t1.flower,t1.birthday,t2.id as gdid, t2.address
        from girl t1,girl_detail t2
        <where>
            t1.id=t2.gid
            and t1.id=#{id}
        where>
    select>
    
    <select id="queryByIdByStep" resultMap="GirlWithDetailMap3">
        select t1.id as uid,t1.`name`,t1.flower,t1.birthday
        from girl t1
        <where>
            and t1.id=#{id}
        where>
    select>
mapper>

##对于javabean的封装多使用oop思想

Girl.java

package com.xuzhi.model;

import java.io.Serializable;
import java.util.Date;

public class Girl implements Serializable {
    private long id;
    private String name;
    private String flower;
    private Date birthday;

    public long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFlower() {
        return flower;
    }

    public void setFlower(String flower) {
        this.flower = flower;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public Girl(String name, String flower){
        this.name=name;
        this.flower=flower;
    }
    public Girl(){

    }

    @Override
    public String toString() {
        return "Girl{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", flower='" + flower + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

GirlWithDetail.java

package com.xuzhi.model;

import java.io.Serializable;

public class GirlWithDetail implements Serializable {
    private Integer gid;
    private String address;
    private Girl girl;

    public Integer getGid() {
        return gid;
    }

    public void setGid(Integer gid) {
        this.gid = gid;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Girl getGirl() {
        return girl;
    }

    public void setGirl(Girl girl) {
        this.girl = girl;
    }

    @Override
    public String toString() {
        return "GirlWithDetail{" +
                "gid=" + gid +
                ", address='" + address + '\'' +
                '}';
    }
}

GirlDetail.java

package com.xuzhi.model;

import java.io.Serializable;

public class GirlDetail extends Girl{
    private GirlWithDetail girlWithDetail;

    public GirlWithDetail getGirlWithDetail() {
        return girlWithDetail;
    }

    public void setGirlWithDetail(GirlWithDetail girlWithDetail) {
        this.girlWithDetail = girlWithDetail;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "id=" + getId() +
                ", name='" + getName() + '\'' +
                ", flower='" + getFlower() + '\'' +
                ", birthday=" + getBirthday() +
                '}'+
                "GirlDetail{" +
                "girlWithDetail=" + girlWithDetail +
                '}';
    }
}

一对多关系映射

##一对多关系映射举例:一个用户可以写多篇博客

##废话不多说,几段代码可以说明一切

GirlWithBlogMapper.xml



<mapper namespace="com.xuzhi.mapper.GirlWithBlogMapper">

    <resultMap id="BaseGirlDetail" type="com.xuzhi.model.GirlDetail">
        <id property="id" column="gid" />
        <result property="name" column="name" />
        <result property="flower" column="flower" />
        <result property="birthday" column="birthday" />
    resultMap>
    <resultMap id="girlWithBlogMap" extends="BaseGirlDetail" type="com.xuzhi.model.GirlBlog" >
        
        <collection property="blog" ofType="com.xuzhi.model.Blog">
            <id property="id" column="bid" />
            <result property="title" column="title" />
            <result property="summary" column="summary" />
            <result property="content" column="blogContent" />
            <collection property="comments" ofType="com.xuzhi.model.Comment">
                <id  property="id" column="cid"/>
                <result property="content" column="commentContent" />
            collection>
    collection>
    resultMap>
    <select id="queryByIdWithBlog" resultMap="girlWithBlogMap">
        SELECT t1.id as gid,t1.`name`,t1.flower,t1.birthday,
        t2.id as bid,t2.title,t2.summary,t2.content as blogContent,
        t3.id as cid,t3.content as commentContent
        from girl t1,blog t2,`comment` t3
        <where>
            t1.id=t2.g_id
            and t2.id=t3.b_id
            and t1.id=#{id}
        where>
    select>
mapper>

Blog.java

package com.xuzhi.model;


import java.util.List;

public class Blog {
    private Integer id;
    private String title;
    private String summary;
    private String content;
    private Girl girl;
    private List<Comment> comments;

    public Integer getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

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

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Girl getGirl() {
        return girl;
    }

    public void setGirl(Girl girl) {
        this.girl = girl;
    }

    public List<Comment> getComments() {
        return comments;
    }

    public void setComments(List<Comment> comments) {
        this.comments = comments;
    }

    @Override
    public String toString() {
        return "Blog{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", summary='" + summary + '\'' +
                ", content='" + content + '\'' +
                ", girl=" + girl +
                ", comments=" + comments +
                '}';
    }
}

Comment.java

package com.xuzhi.model;

public class Comment {
    private Integer id;
    private String content;
    private Blog blog;

    public Integer getId() {
        return id;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Blog getBlog() {
        return blog;
    }

    public void setBlog(Blog blog) {
        this.blog = blog;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", content='" + content + '\'' +
                '}';
    }
}

GirlBlog.java

package com.xuzhi.model;

import java.util.List;

public class GirlBlog extends Girl {
    private List<Blog> blog;

    public List<Blog> getBlog() {
        return blog;
    }

    public void setBlog(List<Blog> blog) {
        this.blog = blog;
    }

    @Override
    public String toString() {
        return  "Girl{" +
                "id=" + getId() +
                ", name='" + getName() + '\'' +
                ", flower='" + getFlower() + '\'' +
                ", birthday=" + getBirthday() +
                '}'+
                "GirlBlog{" +
                "blog=" + blog +
                '}';
    }
}

###简要说明:

​ 在该例中,一个Girl用户可以拥有多个Blog,一个Blog又可以拥有多个Comment,这就构成了简单的一对多关系,其中还是使用了oop思想,最终想要封装的结果集类型是GirlBlog类型,在该类型包含了用户的部分个人信息,还包括了该用户的Blog,在每个Blog中有包含了该Blog所拥有的Comment,在Blog和GirlBlog中分别使用了List和List来反应一对多关系

Spring

基础技术

  • java
  • 反射
  • xml
  • xml解析
  • 代理
  • 大量设计模式

环境搭建

​ 1、添加spring依赖

​ 2、编写一个spring的配置文件

​ 3、通过spring的应用程序上下文对象获取对象

环境配置测试

spring全局配置文件


<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
    
    <bean class="com.xuzhi.pojo.Girl" id="girl">

    bean>

beans>

bean类

###Girl.java

package com.xuzhi.pojo;

public class Girl {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

###测试类–>SpringTest.java

package com.xuzhi.spring;

import com.xuzhi.pojo.Girl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    @Test
    public void test1(){
        // 1、获取上下文对象,spring里面声明对象都需要通过上下文来获取
        //在引入配置文件的时候,可以同时引入多个配置文件,在ClassPathXmlApplicationContext中使用String数组作为参数
        /* 例:ApplicationContext ctx=
        	new ClassPathXmlApplicationContext(new String[]{"xxx1.xml","xxx2.xml"});
        */
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        // 2、通过这个对象来获取girl
        Girl girl= (Girl) ctx.getBean("girl");
        //因为后面指定了class,所以不需要进行强制类型转换(个人感觉这种方式比较好)
        //Girl girl =ctx.getBean("girl",Girl.class);
        System.out.println(girl);
    }
}

普通代码编写与spring方式编写的

​ 普通的获取对象的方式,所有的对象之间的依赖,类之间的依赖关系都是在java代码里面维护的,很难维护的,如果说我们有替换方案,替换比较困难

​ 对象的产生全部是在配置里面完成的,其实我们想分析关系,直接在配置文件里面就看出来了。

核心内容学习
  • IOC
  • AOP​

IOC概念(依赖注入):

​ 控制反转(inverse of contril ):什么控制,谁反转了谁

​ 控制:创建对象,彼此关系的权利

​ 普通方式:控制权是在开发人员在程序代码当中进行掌控,new

​ spring方式:夺取控制权,反转给spring的容器

反转过程:

​ 声明要什么

​ spring容器来进行具体的控制

​ 依赖注入:

​ 依赖:

​ 容器

​ pojos:自己定义的这些类

​ metadata:在spring的配置文件里面写的这些就是元数据

​ 实例化容器:classpath…将配置文件传入,实例化完毕

值的注入

​ setter()方法注入(最常用的方法)

​ 必须其字段有对应的setter()方法才可完成

​ 通过property子节点完成注入

​ 构造注入

bean元素探讨

​ 属性探讨

abstract:该bean将无法被实例化

parent:指定它的父bean是谁,将会继承父bean的所有内容,通过id进行指引

destroy-method:指定这个bean最后销毁的时候一定执行的方法,适合于清理型工作,触发条件是必须bean确实是被销毁才生效

​ 容器close被触发

​ refresh也会触发

​ 过时的destroy也可以触发

init-method:指定bean的初始化方法,准备性的工作

name:别名,可以通过他一样获取,可以写多个,彼此分割可以使用多种分隔符,空格,逗号等等,

<bean class="com.xuzhi.pojo.Girl" id="girl" abstract="true" destroy-method="clearDress" init-method="dress" name="g1,g2,g3">
        
        <property name="name" value="myFirends" />
 bean>

注:clearDress是Girl类里面的一个方法名,dress也是如此,

scope:指定范围

​ singleton:单例,在spring上下文当中,只有一个实例

​ prototype:原型,要一个就给一个

lazy-init:true就是spring一上来不会直接初始化我们的bean,当我们需要使用它的时候,spring才会初始化

​ 直接初始化

​ 当应用程序启动会慢一点,内存消耗会更大一点

​ 当我们使用bean的时候会快一些

​ 延迟初始化

​ 程序启动快一些,内存消耗更小一点

​ 使用bean会慢一点

depends-on:依赖的bean,如果某一个bean的使用严重依赖于另外一个bean的准备的话,就可以配置depends-on

对于非字面值可以描述的值的注入问题

	<bean id="pay" class="com.xuzhi.spring.AliPay">

    bean>
    <bean id="girl" class="com.xuzhi.pojo.Girl" >
        
        <property name="pay" ref="pay" />
    bean>

通过ref指向另外一个bean的ID

关于在spring的配置文件当中单独定义别名

​ alias标签完成

spring多个配置文件里面的bean是可以相互引用的(被上下文扫描到的前提下)

构造注入:

构造注入方式一:


    <bean id="car" class="com.xuzhi.pojo.Car">
        <constructor-arg name="name" value="宝马" />
        <constructor-arg name="price" value="12123123123" />
        <constructor-arg name="speed" value="123123" />
    bean>

构造注入方式二:(不推荐使用,实在是太垃圾了了)


    <bean id="car2" class="com.xuzhi.pojo.Car">
        <constructor-arg index="0" value="宝马" />
        <constructor-arg index="1" value="123123" />
    bean>
public Car(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public Car(double price, double speed) {
        this.price = price;
        this.speed = speed;
    }

    public Car(String name, double price, double speed) {
        this.name = name;
        this.price = price;
        this.speed = speed;
    }

注:他优先时候后面的构造器

构造注入方式三:(不推荐使用,感觉还是很垃圾的)

###根据构造方法里面的参数的类型注入


    <bean id="car3" class="com.xuzhi.pojo.Car" >
        <constructor-arg type="java.lang.String" value="宝马" />
        <constructor-arg type="java.lang.Double" value="123" />
    bean>

Spring中各种值的注入

数组、List、Set、Map

如果其对应的值是简单的字面值,就直接写就可以了,如果是一个其他的类,那么使用内部bean的方式完成

<bean class="com.xuzhi.pojo.People" id="people" >
        <property name="name" value="小明" />
        <property name="age" value="12" />
        <property name="friends">
            <array>
                <value>小红value>
                <value>小刚value>
                <value>你爸爸value>
            array>
        property>
        <property name="numbers">
            <list>
                <value>1value>
                <value>2value>
                <value>3value>
            list>
        property>
        <property name="girls">
            <list>
                
                <bean class="com.xuzhi.pojo.Girl">
                    <property name="name" value="nihao" />
                bean>
                <bean class="com.xuzhi.pojo.Girl">
                    <property name="name" value="测试" />
                bean>
            list>
        property>
        <property name="pays">
            <set>
                <bean class="com.xuzhi.spring.AliPay">

                bean>
                <bean class="com.xuzhi.spring.AliPay">

                bean>
            set>
        property>
        <property name="girlMap">
           	
            <map>
                <entry key="girl1">
                <bean class="com.xuzhi.pojo.Girl">
                    <property name="name" value="nihaoi" />
                bean>
                entry>
                <entry key="girl2">
                    <bean class="com.xuzhi.pojo.Girl">
                        <property name="name" value="nihaoi" />
                    bean>
                entry>
            map>
        property>
    bean>

自动注入

###最新的官方文档推荐是用自动注入

  • byType:按照数据类型注入
  • byName:按照bean对应的pojo里面的属性的名字来进行匹配
  • constructor
    • 有限按照类型去匹配,如果匹配到一个那么直接注入,不止一个按照名字注入,如果一个都找不到,注入失败
  • default
  • none

    
        
        
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
    
    
    

配置文件处理


    
    
    <import resource="classpath:spring/spring-test.xml" />
    <import resource="classpath:spring/spring-test2.xml" />

    
    <import resource="classpath:spring/spring-*.xml" />

    <context:property-placeholder location="classpath:jdbc.properties" />
    <bean class="com.xuzhi.pojo.DaoTest" id="jdbc" >
        
        <property name="url" value="${url}" />
        <property name="driver" value="${driver}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
    bean>

注:使用import等标签时需要完整的xml命名空间

Spring常用注释

  • Component
  • Controller =>(SpringMVC)
  • Service=>(业务层)
  • Respository=>(dao层)

spring AOP

额外补充依赖

<dependency>
    <groupId>org.aspectjgroupId>
    <artifactId>aspectjrtartifactId>
    <version>1.9.2version>
dependency>

<dependency>
    <groupId>org.aspectjgroupId>
    <artifactId>aspectjweaverartifactId>
    <version>1.9.2version>
dependency>
配置文件

<aop:aspectj-autoproxy />

<bean class="com.xuzhi.advice.BeforeAdvice" id="beforeAdvice" >
bean>

<aop:config>
    <aop:aspect id="beforeAspect" ref="beforeAdvice">
        
        
        <aop:before method="methodBefore" pointcut="execution(* com.xuzhi.service.ProviderService.add(..))" />
        <aop:before method="before" pointcut="execution(* com.xuzhi.service.ProviderService.add(..))" />
    aop:aspect>
    <aop:aspect id="afterAspect" ref="afterAdvice">
        
        <aop:after method="methodAfter" pointcut="execution(* com.xuzhi.service.ProviderService.add(String,int))" />
    aop:aspect>
aop:config>
//JoinPoint可以获取几乎所有的这个方法的信息
//作用,可以打印输出日志文件
public void before(JoinPoint joinPoint){
    //获取方法的方法名
    String name=joinPoint.getSignature().getName();
    System.out.println("method:"+name);
    //获取方法的参数
    Object[] args = joinPoint.getArgs();
    System.out.println(Arrays.toString(args));
}

AOP注解版

  • Configuration:表明一个类为配置类,程序启动的时候只要扫描这个类,就可以清楚所有的配置规则
  • Component:表明一个类为spring的一个组件,可以被spring容器所管理,他是一个普通组件的语义
  • Service:同上,语义上属于服务层
  • Repository:同上,语义上属于DAO层
  • Controller:同上,语义上属于控制层
  • ComponentScan:组件扫描,可以决定去扫描那些包
  • Bean:用于在spring容器当中注册一个bean
  • Autowired:自动注入组件

execution表达式

先写访问修饰符,包名的限定,类名,方法名,参数列表+组合条件符合,多个条件很都可以


public com.sz..*.*(String)

public com.sz.*.*.*(Integer )

SpringMVC

使用步骤:

1、创建web项目

2、编写web.xml,在其中注册一个特殊的servlet,前端控制器

3、编写一个springmvc的配置文件

​ 1、注册一个视图解析器

4、编写控制器

5、编写一个结果页面

web.xml


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

    
    <servlet>
        
        <servlet-name>springmvcservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    servlet>
    
    <servlet-mapping>
        <servlet-name>springmvcservlet-name>
        
        <url-pattern>/url-pattern>
    servlet-mapping>

web-app>

依赖引入:



<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>3.1.0version>
    <scope>providedscope>
dependency>


<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.0.8.RELEASEversion>
dependency>
方法一:(貌似是不推荐使用,不太确定)

springmvc-servlet.xml

###springmvc的配置文件,对每一个springmvc控制器都需要配置bean标签


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        
        <property name="prefix" value="/jsp/" />
        
        <property name="suffix" value=".jsp" />
    bean>
    <bean class="com.xuzhi.controller.HelloController" name="/helloController" >

    bean>
beans>

HelloController.java

###控制器,类似于struts的action

package com.xuzhi.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//实现一个Controller接口的方式
public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("hello","Hello World!");
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}

hello.jsp

###视图代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


	Happy New Year:${hello}



SpringMVC分析

组件分析

web.xml

注册前端控制器,目的在于,我们希望让springmvc去处理所有的请求

通过


<servlet-mapping>
    <servlet-name>springmvcservlet-name>
    
    <url-pattern>/url-pattern>
servlet-mapping>

确实是处理所有的请求(不是真的所有)

url-pattern的写法问题

  • / =>(推荐使用)

    • 处理所有的请求,但是和/*不一样,他处理完之后要出去的时候不会再去将这个hello.jsp当做一个新的请求,而是将这个渲染的结构直接返回给浏览器
  • /* =>(永远都不要这么写)

    • 不能写的原因:请求/helloController过去的时候,他的视图名称是hello,hello.jsp页面,他将其当做了一个叫hello.jsp的请求,尝试去匹配对应的Controller,但是我的容器当中根本不存在这样的controller,所以无法匹配,导致404
  • *.do

    • 这种方式,有的开发团队习惯将请求的行为加个小尾巴用以区分,.do,.action

关于前端控制器的解释

springmvc设计的理念是希望开发者尽量远离原生的servletAPI,API不是很好用,有些繁琐,将操作进一步的简化,他将很多东西责任进行了拆分,不希望我们将一些技术点绑定死,可以做到随意的切换。本身还是基于servlet设计的,分发的servlet,

springmvc配置文件名字的问题

默认情况下是dispatcherServlet的名字当做命名空间

[ServletName]-servlet.xml (WEB-INF)

servletName-servlet.xml = namespace.xml

之下寻找

降配置文件移动位置之后,出现了相应的错误

如果非要重新使用另外一个名字,可以使用


<init-param>
    <param-name>namespaceparam-name>
    <param-value>mvcparam-value>
init-param>

默认的规则要求在web-inf下,但是maven项目的标准应该在resources下面,解决方案:

重新指定上下文的配置文件的位置即可

<init-param>
    
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:springmvc-servlet.xmlparam-value>
init-param>

视图解析器

springmvc支持多种视图技术

  • jsp
  • freemaker

内部的资源视图解析器

  • 视图前缀
    • /jsp/他是我们的请求相应的资源的路径的配置, viewName:hello /jsp/hello
  • 视图后缀
    • .jsp 此时我们的前缀+视图名称+后缀 =/jsp/hello.jsp

解析器的作用类似于

request.getDispatcherServlet.forward(request,response);

物理视图是由逻辑视图转换而来

物理视图是webapp/jsp/hello.jsp

逻辑视图 p View =prefix + logicViewName + suffix

  • prefix => 前缀
  • logicViewName =>视图名称(在Controller中的ModelAndView的setViewName()方法来指定)
  • suffix =>后缀

控制器

是一种比较传统的实现一个接口的方式完成的,Controller

如果一个接口只有一个方法,这种接口叫做函数式接口

###ModelAndView方法是Controller接口内的唯一的一个方法,故Controller为函数式接口

@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, 									HttpServletResponse httpServletResponse) throws Exception {
   
}

该代码类似于servlet里面由doGet doPost里面入参就是请求与相应。

在springmvc中,在model当中填充数据,然后在具体的视图进行展示

还需要在配置文件当中配置一下bean,这个bean要取个名字,就用来充当这个URI,他就处理一个请求,跟servlet的差别不是很大。

注解开发模式(方法二:推荐使用)

基于实现接口的方式已经是过去式了,采用注解开发很简单

基本注解
  • @Controller

  • @RequestMapping

    • 可以写在方法上
    • 也可以写在类上

    ###推荐使用二者结合的方式

    组合使用实例

    @Controller
    @RequestMapping("/bye")
    public class ByeController {
        //要想访问该Controller具体的地址应该是":8080/bye/bye"
        @RequestMapping("/bye")
        public String bye(Model model){
            model.addAttribute("hello","我的世界");
            //返回的为viewName,即视图的名字,此时寻找视图的路径为 /jsp/hello.jsp
            return "hello";
        }
    }
    

    ###使用联合方式,第一个/bye可以区分大类,第二个/bye直接调用该具体Controller

springmvc-servlet.xml

###需要添加相应的命名空间,以使用Context


<context:component-scan base-package="com.xuzhi.controller" />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    
    <property name="prefix" value="/jsp/" />
    
    <property name="suffix" value=".jsp" />
bean>
Controller.java
package com.xuzhi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
//使用注解需要在springmvc的配置文件里面导入一个包,以启动注解扫描
//不需要继承任何的类也不需要实现任何的接口
@Controller
public class ByeController {
    @RequestMapping
    public String bye(Model model){
        //往view层传值
        model.addAttribute("hello","我的世界");
        //返回的为viewName,即视图的名字,此时寻找视图的路径为 /jsp/hello.jsp
        return "hello";
    }
}
注解开发步骤总结:

1、配置基础扫描的包,这样配置的注解才会生效

2、在指定的类上面添加@Controller注解

3、在Controller类的方法前添加@RequestMapping注解,类似于前面的Controller的那个名字(不同requesthandler处理的handlerMapping)

当我们写上Controller之后,就标记了它为spring的一个组件,并且是控制器的组件,此时我们的handlermapping会去扫描寻找这个controller是否与之匹配,如果发现匹配就把这里处理的工作交给它

匹配的规则:

具体的匹配就是通过请求的路径进行匹配的

@RequestMapping(URI)

此时就是通过这个URI进行匹配

转发与重定向

转发

//请求
@RequestMapping("/forward")
public String forward(Model model){
    //springmvc model默认是在请求域中存储值
    System.out.println("请求");
    model.addAttribute("skill","请求测试");
    return "forward";
}

重定向

//重定向
@RequestMapping("/redirect")
public String redirect(Model model){
    model.addAttribute("skill","重定向测试");
    System.out.println("重定向");
    //重定向是需要在return的内容中增加重定向的标识=>“redirect:”+重定向视图的路径
    return "redirect:/jsp/redirect.jsp";
}
  • 转发到页面 (默认)

  • 重定向到页面 redirect:path

  • 转发到另外一个控制器 forward:path

关于springmvc访问web元素

  • request

  • session

  • application

可以通过模拟的对象完成操作,也可以使用原生的servletAPI完成,直接在方法当中入参即可

package com.xuzhi.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/web")
public class WebElementController {

    //request元素
    @RequestMapping("request")
    public String request(WebRequest request){
        System.out.println(request.getParameter("test"));
        return "forward";
    }
    //session元素
    @RequestMapping("session")
    public String session(HttpSession session){
        session.setAttribute("test","我是你爸爸");
        return "forward";
    }
    //application元素
    @RequestMapping("application")
    public String application(HttpSession session){
        //获取application并设置test
        session.getServletContext().setAttribute("application","application测试");
        return "redirect:/jsp/forward.jsp";
    }
}

注解详解

@RequestMapping
  • value 写的是路径,是一个数组的形式,可以匹配多个路径

  • path 是value的别名,所以二者人选其一,他们的作用是一样的

  • method 指定可以访问的请求的类型,比如post,get,他也可以写成一个数组的形式

  • params 可以指定参数,还可以去限定这个参数的特征,比如等于某个值

    • params={“girl=a”,“boy!=b”} =>当请求的参数girl等于a,boy不等于b的时候才能继续向下执行
  • headers 能够影响浏览器的行为

  • consumers 消费者,媒体类型,可以限定为application.json;charset=UTF-8

  • produces 产生的响应的类型

    //请求映射的路径path可以有多个值,即请求这个controller可以用多个名字,m1,m2都可以请求这个			Controller
    //    @RequestMapping(value = {"/m1","/m2"})
    //    @RequestMapping(path = {"/m1","/m2"})
    //该请求只能接受post提交的表单
    @RequestMapping(path = {"/m1","/m2"},method = RequestMethod.POST)
    public String m1(Model model){
        model.addAttribute("annotations","@RequestMapping注解");
        return "annotations";
    }
    
    //用以处理post请求,参数为两个,分别为a和b
    @RequestMapping(path = "/m2",method = RequestMethod.GET,params = {"a","b"})
    public String m2(@RequestParam("a")Integer a, @RequestParam("b") Integer b){
        System.out.println(a+b);
        return "annotations";
    }
    
@GetMapping,@PostMapping…

​ 相等于RequestMapping中的method指定为get或者post,只能相应处理get或者post请求

@PathVariable

resultful风格

###请求时的url可以写成=》/product/add/产品id/产品名称/产品价格

​ 该Controller可以自动接收通过url传入的参数

@Controller
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/add/{id}/{name}/{price}")
    public String addProduct(@PathVariable("id")Integer id,@PathVariable("name")String 												name,@PathVariable("price")Double price){
        System.out.println(id+name+price);
        return "forward";
    }
}

对于非get,post请求的支持 // TODO

对于非get,post请求的支持,需要有额外的内容添加,要增加一个过滤器来额外处理

他返回的不是页面,而是数据

  • DeleteMapping

  • PutMapping

  • 过滤器

    
        <filter>
            <filter-name>hiddenHttpMethodFilterfilter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
        filter>
        <filter-mapping>
            <filter-name>hiddenHttpMethodFilterfilter-name>
            <url-pattern>/*url-pattern>
        filter-mapping>
    
  • 表单提交里面还要添加一个隐藏的参数

@PutMapping

关于获取项目名称的问题

@WebServlet(urlPatterns = {},loadOnStartup = 2)
public class WebPathInitServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        //在整体应用上下文当中存储了一个ctx的值,用他来引用上下文路径
        config.getServletContext().setAttribute("ctx",config.getServletContext().getContextPath());
        super.init(config);
    }
}

###在jsp页面中需要全局项目名称时只需要引用${ctx},在此后的访问静态资源时会使用

关于请求路径的问题

springmvc支持ant风格

  • ?任意的字符

  • “*” 0到n,任意个字符都可以,/除外

  • ** 支持任意层路径,

    //    访问地址可以写为"/test/m3"+"任意单个字符,/除外"
    //    @RequestMapping(path = "/m3?")
    //    访问地址可以写为"/test/m3"+"可以放任意长度的字符串,但是不能包括/"
    //    @RequestMapping(path = "m3*")
    //    访问地址可以写为"/m3"+"/a"+"/b",可以有多层路径
        @RequestMapping(path = "m3/**")
        public String m3(){
            System.out.println("m3....");
            return "annotations";
        }
    

关于静态资源访问的问题

由于我们的servlet设置了URL匹配方式为/,所以,他将静态资源也当做一个后台的请求,

比如http://localhost:8080/SpringMVC/static/css/index.css

他尝试去匹配一个static/css/index.css的Controller里面的requestMapping的组合,因为没有,所以404,解决方式很多,最简单的,是让springmvc单独处理,将这些交给容器的默认的servlet处理,就不让DispatcherServlet来处理了

解决方式一(推荐使用这种方式,当需要引用的文件不能被识别时,可以增加第二种方式来引入)



<mvc:default-servlet-handler />
<mvc:annotation-driven />

解决方式二

<mvc:resources mapping="static/css/*" location="static/css/" />

关于post请求中文乱码问题的解决

添加一个过滤器即可,springmvc提供了非常好的字符编码过滤器,所以我们注册即可

在web.xml中添加这样的配置进行注册(最好是放在servlet过滤器之前)


<filter>
    <filter-name>characterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    
    <init-param>
        <param-name>encodingparam-name>
        <param-value>UTF-8param-value>
    init-param>
    <init-param>
        <param-name>forceRequestEncodingparam-name>
        <param-value>trueparam-value>
    init-param>
filter>
<filter-mapping>
    <filter-name>characterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

关于form表单提交数据的方式

方式一 通过属性名绑定

通过属性名称进行绑定,可以完成数据绑定

页面当中表单元素的name值要和后台的形参的名字保持一致。

如果有多个,多个形参按名字绑定即可,当传入的值校对的时候,会比较麻烦

@PutMapping("put")
@ResponseBody
//形参要与前台页面传过来的name名称相对应
public String put(String name){
    System.out.println(name);
    return "@PutMapping测试成功";
}
方式二 利用@RequestParam注解

jsp页面不变

后台

@PutMapping("put")
@ResponseBody
public String put1(@RequestParam("name") String name){
    System.out.println(name);
    return "@PutMapping测试成功";
}
方式三 直接使用pojo形式传递

jsp页面一致

@PutMapping("/put2")
@ResponseBody
public String put2(User user){
    System.out.println(user.getName()+user.getPassword());
    return "@PutMapping测试成功";
}

关于form表单提交日期格式数据问题的处理

1、处理日期(没有时间)
@InitBinder("user")
public void init(WebDataBinder webDataBinder){
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    webDataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
}
@PostMapping("/model3")
public String model3(@ModelAttribute("user") User user){
    System.out.println(user.getName()+user.getPassword());
    System.out.println(user.getBirth());
    return "msg";
}
//通过initBinder指定了user名字和modelAttribute里面的user绑定

2、不指定名字,根据数据类型一样可以分析解析转换成功

@InitBinder()
public void init(WebDataBinder webDataBinder){
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    webDataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
}
@PostMapping("/model3")
public String model3(@ModelAttribute() User user){
    System.out.println(user.getName()+user.getPassword());
    System.out.println(user.getBirth());
    return "msg";
}

3、时间+日期的处理(推荐使用注解方式)

//通过Java源码的方式(如1、2),解决方案不是很理想,只能处理固定格式的时间日期格式,个人建议使用注解的方式来解决	比较好
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;

注解补充

@ResponseBody

返回数据,一般情况下返回json格式,需要引用json包

put.jsp =>put请求方式为例

UserController.java

@Controller
@RequestMapping("/user")
public class UserController {
    //相应put请求
    @PutMapping("put")
    //表示将返回一个数据结果,而不是页面
    @ResponseBody
    public String put(String name){
        System.out.println(name);
        //返回数据,为测试方便,结果返回一个String字符串
        return "@PutMapping测试成功";
    }
}
@ModelAttribute

使用方式一:

//就是在controller里面的任意一个处理具体的方法之前执行
@ModelAttribute
public User init(){
    User u=new User();
    u.setName("王是你爸爸");
    return u;
}
@RequestMapping("/model")
public String model(Model model){
    //判断init()方法是否在该方法之前执行,即判断init()方法是否返回了User对象,同时确定了			init()返回的对象名是什么
    System.out.println(model.containsAttribute("user"));
    System.out.println(model.addAttribute("user"));
    return "msg";
}

如果某些对象从头到尾每次请求当中都要存在,不消失,就适合使用这种方法。

使用方式二

//就是在controller里面的任意一个处理具体的方法之前执行
@ModelAttribute
public void init(Model model){
    User u=new User();
    u.setName("王是你爸爸");
    model.addAttribute("user",u);
}
@RequestMapping("/model")
public String model(Model model){
    //判断init()方法是否在该方法之前执行,即判断init()方法是否返回了User对象,同时确定了init()返回的对象名是什么
    System.out.println(model.containsAttribute("user"));
    System.out.println(model.addAttribute("user"));
    return "msg";
}

使用方式三:

//如果前台没有传过来相应的值,使用该注解后会自动去我们的model模型中寻找相应的user,
//如果前台传值过来,则init()方法返回的内容则由前台穿过来的model模型替换
@RequestMapping("/model2")
public String model2(@ModelAttribute User user){
    System.out.println(user.getName()+user.getPassword());
    return "msg";
}
@InitBinder
@DateTimeFormat

用以标记处理springmvc的中传值时间日期问题,格式化时间日期

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
@RequestBody

json数据,不是通过form表单传递

ajax({
	data:
})
@SessionAttributes
@Controller
@RequestMapping("/user3")
@SessionAttributes("user")
public class User3Controller {
    @PostMapping("/session")
    public String session(User user){
        return "redirect:/jsp/user.jsp";
    }
}
@SessionAttribute

要求当前这次访问当中的会话当中必须有某个对象,简而言之,@SessionAttributes是往会话中添加某个模型数据,而@SessionAttribute是为了检查当前会话中是否有需要检测的模型数据

@RestController

@RestController=@Controller+@ResponseBody

该注解标记的Controller类可以指定该Controller类中的所有方法都返回数据,而不是返回页面

JSON数据交互

添加相关依赖



<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-databindartifactId>
    <version>2.9.5version>
dependency>

<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-coreartifactId>
    <version>2.9.5version>
dependency>

<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-annotationsartifactId>
    <version>2.9.5version>
dependency>

<dependency>
    <groupId>net.sf.json-libgroupId>
    <artifactId>json-libartifactId>
    <version>2.4version>
    <classifier>jdk15classifier>
dependency>


<dependency>
    <groupId>org.codehaus.jacksongroupId>
    <artifactId>jackson-core-aslartifactId>
    <version>1.9.2version>
dependency>

<dependency>
    <groupId>org.codehaus.jacksongroupId>
    <artifactId>jackson-mapper-aslartifactId>
    <version>1.9.2version>
dependency>

JSON如何返回前台

1、返回一个pojo
//返回一个pojo
@RequestMapping("/m1")
@ResponseBody  //这个注解将制定返回的不是视图,而是数据,他会将我们的返回数据格式转换为json数据格式
public User json1(){
    User user=new User();
    user.setName("我是你爸爸");
    user.setPassword("root");
    return user;
}
2、返回一个Map
//返回一个Map
@RequestMapping("/m2")
@ResponseBody  //这个注解将制定返回的不是视图,而是数据,他会将我们的返回数据格式转换为json数据格式
public Map<String,Object> json2(){
    Map<String,Object> map=new HashMap<>();
    map.put("name","你爸爸就是你爸爸");
    map.put("age",21);
    return map;
}
3、返回一个数组
@RequestMapping("/m3")
@ResponseBody
public User[] json3(){
    User user1=new User();
    user1.setName("我是你爸爸1");
    user1.setPassword("你爸爸");
    User user2=new User();
    user2.setName("你爸爸就是你爸爸");
    user2.setPassword("你就是你");
    return new User[]{user1,user2};
}
4、返回一个list
@RequestMapping("/m4")
@ResponseBody
public List<User> json4(){
    List<User> list=new ArrayList<>();
    User user1=new User();
    user1.setName("我是你爸爸");
    user1.setPassword("你爸爸");
    User user2=new User();
    user2.setName("你爸爸就是你爸爸");
    user2.setPassword("你就是你");
    list.add(user1);
    list.add(user2);
    return list;
}

JSON如何在前台解析

1、解析返回的pojo
$.ajax({
    url:'${ctx}/json/m1',
    type:'post',
    success:function (data) {
        alert(data.name);
        alert(data.password);
    }
})
2、解析返回的map
//接收返回的map
$('#map').click(function () {
    $.ajax({
        url:'${ctx}/json/m2',
        type:'post',
        success:function (data) {
            alert(data.name);
            alert(data.age);
        }
    })
})
3、解析返回的数组
//接收返回的数组
$('#array').click(function () {
    $.ajax({
        url:'${ctx}/json/m3',
        type:'post',
        success:function (data) {
            for(var i=0;i<data.length;i++){
                alert(data[i].name);
                alert(data[i].password);
            }
        }
    })
})
4、解析返回的list
//接收返回的数组
$('#list').click(function () {
    $.ajax({
        url:'${ctx}/json/m4',
        type:'post',
        success:function (data) {
            for(var i=0;i<data.length;i++){
                alert(data[i].name);
                alert(data[i].password);
            }
        }
    })
})

JSON如何将数据传到后台

必须要添加,来规范传输json数据格式以及编码标准

contentType:"application/json;charset=utf-8"
1、前台ajax向后台发送一个pojo
$('#user').click(function () {
    var obj={
        "name":"我是你爸爸",
        "password":"你爸爸就是你爸爸"
    };
    $.ajax({
        url:'${ctx}/json2/add',
        type:'post',
        contentType:'application/json',
        data:JSON.stringify(obj),
        success:function (data) {

        }
    })
})
//前台提交一个user过来
@RequestMapping("/add")
//User user入参只能处理form表单提交的数据
//要想接收前台ajax发过来的json数据,需在入参时添加@RequestBody注解
public String add(@RequestBody User user){
    System.out.println(user.getName()+user.getPassword());
    return "msg";
}
2、前台ajax向后台发送一组pojo
$('#userList').click(function () {
    var obj={
        "name":"我是你爸爸",
        "password":"你爸爸就是你爸爸"
    };
    var obj2={
        "name":"我是你爷爷",
        "password":"你爷爷就是你爷爷"
    };
    var array=new Array();
    array.push(obj);
    array.push(obj2);
    $.ajax({
        url:'${ctx}/json2/addList',
        type:'post',
        contentType:'application/json',
        data:JSON.stringify(array),
        success:function (data) {
            if(data.code==2000){
                alert("测试成功");
            }
        }
    })
})
//前台提交一个user过来
@RequestMapping("/addList")
//User user入参只能处理form表单提交的数据
//要想接收前台ajax发过来的json数据,需在入参时添加@RequestBody注解
@ResponseBody
public Map<String,Integer> addList(@RequestBody List<User> user){
    Map<String,Integer> map=new HashMap<>();
    map.put("code",2000);
    System.out.println(user);
    return map;
}

XML数据交互

对于很多第三方开发,还是有很多会采用xml作为数据交互,比如微信

添加额外依赖


<dependency>
    <groupId>com.fasterxml.jackson.dataformatgroupId>
    <artifactId>jackson-dataformat-xmlartifactId>
    <version>2.9.3version>
dependency>a
方法测试

##仅作为小测试,需要用时自行查阅

//produces用于指定返回数据的数据类型,在这里我们指定为XML格式
@RequestMapping(value = "/m1",produces = MediaType.APPLICATION_ATOM_XML_VALUE)
@ResponseBody
public User m1(){
    User user=new User();
    user.setName("我是你爸爸");
    user.setPassword("你爸爸就是你爸爸");
    return user;
}

文件上传与下载

文件上传

方式一:Apache Upload文件上传方式

1、添加相关依赖



<dependency>
    <groupId>commons-fileuploadgroupId>
    <artifactId>commons-fileuploadartifactId>
    <version>1.3.3version>
dependency>

2、在springmvc的配置文件中注册一个文件上传解析器


<bean id="multipartResolver" 		        						        			class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    
    <property name="maxUploadSize" value="1048576" />
    
    <property name="defaultEncoding" value="UTF-8" />
    
    <property name="maxUploadSizePerFile" value="1024" />
bean>

3、准备一个上传的页面

<%--要实现文件上传,必须要添加enctype="multipart/form-data" --%>
文件:

4、后台处理程序

@Controller
@RequestMapping("/file")
public class FileController {

    private static String uploadPath="I:/newFile/";

    /**
     * 文件上传要处理的问题
     * 1、传到哪里去;2、要传什么东西;3、文件传输的细节
     * @param multipartFile
     * @return
     */
    @RequestMapping("/upload")
    public String upload(@RequestParam("upload")MultipartFile multipartFile, Model model){

        //1、判断上传的文件是否为空
        if(multipartFile!=null && !multipartFile.isEmpty()){
            //2、获取上传文件的原始文件名
            String originalFilename = multipartFile.getOriginalFilename();

            //3、截取源文件名的前缀,不带后缀
            String fileNamePrefix=originalFilename.substring(0,originalFilename.lastIndexOf("."));

            //4、加工处理原文件名,原文件名+时间戳
            String newFileNameProfix=fileNamePrefix+new Date().getTime();

            //5、得到新的文件名
            String newFileName=newFileNameProfix+originalFilename.substring(originalFilename.lastIndexOf("."));

            //6、构建文件对象
            File file =new File(uploadPath+newFileName);

            //7、上传
            try {
                multipartFile.transferTo(file);
                model.addAttribute("fileName",newFileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }
}

文件下载

@Controller
@RequestMapping("/download")
public class DownloadController {

    //定义一个文件下载的路径
    private static String DownloadPath="I:/newFile/";

    //
    @RequestMapping("/down")
    public String download(HttpServletResponse response){
        //通过输出流写入到客户端
        //1、获取文件下载名
        String fileName="typora-setup-x64.exe";

        //2、构建一个文件对象通过Paths工具类获取一个Path对象
        Path path = Paths.get(DownloadPath, fileName);

        //3、判断文件是否存在
        if(Files.exists(path)){
            //存在则此下载
            //通过response设定它响应的类型
            //4、获取文件的后缀,即获取文件的类型
            String fileSuffix=fileName.substring(fileName.lastIndexOf(".")+1);

            //5、设置contentType,只有指定他才能下载文件
            response.setContentType("application/"+fileSuffix);

            //6、添加头信息
            //因为是springmvc只能处理ISO8859-1,所以要将文件名通过UTF-8提取出字节流名称再转换成标					准的ISO8859-1
            try {
                response.setHeader("Content-Disposition","attachment;filename="+new String(fileName.getBytes("UTF-8"),"ISO8859-1"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            //7、通过path写出该文件
            try {
                Files.copy(path,response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }
}

拦截器

springmvc提供了拦截器,类似于过滤器,他将在我们的请求距离之前先做检查,有权决定,接下来是否继续,对我们的请求进行加工。拦截器,可以设计多个,

通过实现HandlerIntercepror,这是一个接口,定义了三个非常重要的方法

  • 前置处理
  • 后置处理
  • 完成处理

案例一,运行时间计算与好坏判断

后台代码

package com.xuzhi.interceptors;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 方法耗时统计的拦截器
 */
public class MethodTimerInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER=Logger.getLogger(MethodTimerInterceptor.class);


    //前置功能 开始到结束,计算两个点之间所需要的时间
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1、定义开始时间
        long start=System.currentTimeMillis();
        //2、将开始时间存到请求域当中
        request.setAttribute("start",start);
        //记录请求日志
        LOGGER.info(request.getRequestURI()+"请求到达!");
        //返回true,才会去找下一个拦截器,如果没有下一个拦截器,则去到Controller执行请求
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //1、得到开始的时间
        long start= (long) request.getAttribute("start");
        //2、得到结束的时间
        long end=System.currentTimeMillis();
        //3、计算耗时
        long speedTime=end-start;
        if(speedTime>=1000){
            LOGGER.warn("请求耗时严重,耗时:"+speedTime+"毫秒");
        }else{
            LOGGER.info("请求耗时正常,耗时:"+speedTime+"毫秒");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

配置文件

<mvc:interceptor>
            
            <mvc:mapping path="/**/*"/>
            <bean class="com.xuzhi.interceptors.MethodTimerInterceptor" />
mvc:interceptor>

案例二:Session拦截器

后台代码

package com.xuzhi.interceptors;

import com.xuzhi.pojo.User;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 会话拦截器
 */
public class SessionInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER=Logger.getLogger(SessionInterceptor.class);

    //检查当前会话是不是有该User,如果有,放行,如果没有,则拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取会话中的User对象
        Object user=request.getSession().getAttribute("SESSION_USER");

        //判断该用户是否登录,
        if(user == null){
            LOGGER.warn("您不具备该权限,请先登录");
            return false;
        }

        //先判断user是否为空,即判断用户是不是登录
        //如果用户登录,则判断用户是不是User类型
        if(user instanceof User){
            //去数据库检测该用户是否存在,给予该用户冻结状态,密码附空
            User u= (User) user;
            u.setPassword(null);
            request.getSession().setAttribute("SESSION_USER",u);
            LOGGER.info(u.getName()+"登录状态");
            return true;
        }else{
            LOGGER.warn("请先登录,不要搞事情");
            return false;
        }
    }
}

配置文件

<mvc:interceptor>
    
    <mvc:mapping path="/user/**/*"/>
    <mvc:exclude-mapping path="/user/login" />
    <bean class="com.xuzhi.interceptors.SessionInterceptor">

    bean>
mvc:interceptor>

拦截器执行顺序的问题

如果有n个拦截器,并且都能拦截到某个URI的时候,执行顺序问题,

在springmvc中当中拦截器定义的先后顺序有关系,配置在前面的优先执行,按照顺序来

例如:有三个拦截器 i1.i2.i3

前置处理顺序:i1,i2,i3

后置处理顺序:i3,i2,i1

拦截器与过滤器的比较

  • 相似:都有优先处理请求处理的权利,可以决定是否将请求转移到实际处理的控制器处,都可以对请求或者会话当中的数据进行加工
  • 不同:
    • 拦截器可以做前置处理,也可以做后置处理,还可以完成后处理,控制更加细一些,过滤器只负责前面的过滤的行为而已
    • 过滤器优先执行
    • 过滤器是servlet规范里面的组件
    • 拦截器都是框架自己额外添加的组件

SSM整合

spring和springmvc是天然集成,所以只需要解决mybatis和spring整合的问题,中间项目mybatis-spring项目进行整合

  • 由spring容器管理mybatis这个mapper
  • 由spring利用声明式事务(AOP)进行事务综合管理

添加依赖

<dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
    <scope>testscope>
dependency>


<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>3.1.0version>
    <scope>providedscope>
dependency>

<dependency>
    <groupId>javax.servlet.jspgroupId>
    <artifactId>javax.servlet.jsp-apiartifactId>
    <version>2.3.1version>
    <scope>providedscope>
dependency>

<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>jstlartifactId>
    <version>1.2version>
dependency>



<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-contextartifactId>
    <version>5.0.8.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-context-supportartifactId>
    <version>5.0.8.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-beansartifactId>
    <version>5.0.8.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-aopartifactId>
    <version>5.0.8.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-aspectsartifactId>
    <version>5.0.8.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-jdbcartifactId>
    <version>5.0.8.RELEASEversion>
dependency>


<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-txartifactId>
    <version>5.0.8.RELEASEversion>
dependency>


<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webartifactId>
    <version>5.0.8.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.0.8.RELEASEversion>
dependency>




<dependency>
    <groupId>org.mybatisgroupId>
    <artifactId>mybatisartifactId>
    <version>3.4.6version>
dependency>


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.38version>
dependency>



<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-databindartifactId>
    <version>2.9.5version>
dependency>

<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-coreartifactId>
    <version>2.9.5version>
dependency>

<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-annotationsartifactId>
    <version>2.9.5version>
dependency>

<dependency>
    <groupId>net.sf.json-libgroupId>
    <artifactId>json-libartifactId>
    <version>2.4version>
    <classifier>jdk15classifier>
dependency>


<dependency>
    <groupId>org.codehaus.jacksongroupId>
    <artifactId>jackson-core-aslartifactId>
    <version>1.9.2version>
dependency>

<dependency>
    <groupId>org.codehaus.jacksongroupId>
    <artifactId>jackson-mapper-aslartifactId>
    <version>1.9.2version>
dependency>



<dependency>
    <groupId>commons-fileuploadgroupId>
    <artifactId>commons-fileuploadartifactId>
    <version>1.3.3version>
dependency>



<dependency>
    <groupId>com.fasterxml.jackson.dataformatgroupId>
    <artifactId>jackson-dataformat-xmlartifactId>
    <version>2.9.3version>
dependency>


<dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>slf4j-apiartifactId>
    <version>1.7.2version>
dependency>

<dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>slf4j-log4j12artifactId>
    <version>1.7.2version>
    <scope>testscope>
dependency>
<dependency>
    <groupId>log4jgroupId>
    <artifactId>log4jartifactId>
    <version>1.2.17version>
dependency>



<dependency>
    <groupId>com.mchangegroupId>
    <artifactId>c3p0artifactId>
    <version>0.9.2.1version>
dependency>



<dependency>
    <groupId>org.mybatisgroupId>
    <artifactId>mybatis-springartifactId>
    <version>1.3.0version>
dependency>



<dependency>
    <groupId>joda-timegroupId>
    <artifactId>joda-timeartifactId>
    <version>2.9.9version>
dependency>



<dependency>
    <groupId>com.github.pagehelpergroupId>
    <artifactId>pagehelperartifactId>
    <version>5.1.2version>
dependency>



<dependency>
    <groupId>commons-codecgroupId>
    <artifactId>commons-codecartifactId>
    <version>1.10version>
dependency>

web.xml配置

注册spring的上下文文件

<context-param>
    
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:/spring/applicationContext.xmlparam-value>
context-param>
字符编码以及全HTTP请求支持过滤器添加

<filter>
    <filter-name>characterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    
    <init-param>
        <param-name>encodingparam-name>
        <param-value>UTF-8param-value>
    init-param>
    <init-param>
        <param-name>forceRequestEncodingparam-name>
        <param-value>trueparam-value>
    init-param>
    <init-param>
        <param-name>forceResponseEncodingparam-name>
        <param-value>trueparam-value>
    init-param>
filter>
<filter-mapping>
    <filter-name>characterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

<filter>
    <filter-name>hiddenHttpMethodFilterfilter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>
DispatcherServlet注册

<servlet>
    
    <servlet-name>springmvcservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    
    
    
    
    
    <init-param>
        
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:springmvc-servlet.xmlparam-value>
    init-param>
servlet>

<servlet-mapping>
    <servlet-name>springmvcservlet-name>
    
    <url-pattern>/url-pattern>
servlet-mapping>
spring启动监听器配置

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>

spring核心配置文件编写

核心配置文件用于引入其他配置文件

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    
    <import resource="classpath:spring/spring-*.xml"/>
beans>
spring-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
                           http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
                           http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
                           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
                           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd ">
    
    <context:component-scan base-package="com.xuzhi" >
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"  />
    context:component-scan>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/pages/" />
        <property name="suffix" value=".jsp" />
    bean>
    
    <mvc:default-servlet-handler />
    
    <mvc:annotation-driven>
        
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8value>
                    list>
                property>
            bean>
        mvc:message-converters>
    mvc:annotation-driven>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes" >
                        <list>
                            <value>text/html;charset=UTF-8value>
                        list>
                    property>
                bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8value>
                            <value>application/json;charset=UTF-8value>
                        list>
                    property>
                bean>
            list>
        property>
    bean>
    
    
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        
        <property name="maxUploadSize" value="1073741824" />
        
        <property name="defaultEncoding" value="UTF-8" />
        
        <property name="maxUploadSizePerFile" value="4194304" />
    bean>

beans>
spring-mybatis.xml

整合ORM功能


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
                           http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
                           http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
                           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
                           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd ">
    <context:component-scan base-package="com.xuzhi.mapper">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    context:component-scan>
    
    <context:property-placeholder location="classpath:jdbc.properties" />
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${driver}" />
        <property name="jdbcUrl" value="${url}" />
        <property name="user" value="${username}" />
        <property name="password" value="${password}" />
        
        
        <property name="maxPoolSize" value="30" />
        <property name="minPoolSize" value="10" />
        
        <property name="autoCommitOnClose" value="false" />
        
        <property name="checkoutTimeout" value="100000" />
        
        <property name="acquireRetryAttempts" value="2" />
    bean>
    
    
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean" >
        <property name="dataSource" ref="dataSource" />
        
        
        
        <property name="mapperLocations" value="classpath:com/xuzhi/mapper/**/*.xml" />
        <property name="configLocation">
            <bean class="org.apache.ibatis.session.Configuration">
                
                <property name="mapUnderscoreToCamelCase" value="true" />
            bean>
        property>
        
        <property name="plugins" >
            <array>
                
                <bean class="com.github.pagehelper.PageInterceptor">
                    
                    <property name="properties">
                        <value>
                            helperDialect=mysql
                            reasonable=true
                            supportMethodArguments=true
                            params=count=countSql
                            autoRuntimeDialect=true
                        value>
                    property>
                bean>
            array>
        property>
    bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.xuzhi.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" />
    bean>
    
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" value="dataSource" />
    bean>
    
    <tx:advice transaction-manager="transactionManager" id="transactionAdvice">
        
        <tx:attributes>
            
            <tx:method name="select*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
            <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception" />
        tx:attributes>
    tx:advice>
    
    <aop:config>
        <aop:pointcut id="txCut" expression="execution(* com.xuzhi.service..*.*(..))" />
        <aop:advisor advice-ref="transactionAdvice" pointcut-ref="txCut" />
    aop:config>
    
    <tx:annotation-driven transaction-manager="transactionManager" />

beans>
spring-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
                           http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
                           http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
                           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
                           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd ">
    
    
    <context:annotation-config />
    
    <context:component-scan base-package="com.xuzhi" />
    
    <aop:aspectj-autoproxy />

    
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionService" >
        <property name="registerDefaultFormatters" value="false" />
        <property name="formatters">
            <set>
                <bean class="org.springframework.format.number.NumberFormatAnnotationFormatterFactory" />
            set>
        property>
        <property name="formatterRegistrars">
            <set>
                <bean class="org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar" >
                    <property name="dateFormatter">
                        <bean class="org.springframework.format.datetime.joda.DateTimeFormatterFactoryBean">
                            <property name="pattern" value="yyyyMMdd" />
                        bean>
                    property>
                bean>
            set>
        property>
    bean>

beans>

你可能感兴趣的:(SSM框架学习)