SSM框架——SpringMVC+Spring+Mybatis搭建教程

一、概述

  • Spring: Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地`new`一个对象,而是让Spring框架帮你来完成这一切。
  • SpringMVC: SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。SpringMVC相当于SSH框架中struts。
  • Mybatis: mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。

页面发送请求给控制器,控制器调用业务层处理逻辑,逻辑层向持久层发送请求,持久层与数据库交互,后将结果返回给业务层,业务层将处理逻辑发送给控制器,控制器再调用视图展现数据。

二、项目搭建

1.开发环境

  Eclipse + Tomcat8 + JDK1.8 + maven + ORACLE

2.使用maven管理项目

  使用以下命令创建webapp项目,使用命令要注意,系统安装了Maven,并配置好了环境变量!

mvc archetype:generate -DgroupId=com.osgc -DartifactId=MobileProducts -DarchetypeArtifactId=maven-archetype-webapp

3.搭建SSM项目

  1).导入项目,添加依赖

  在Eclipse中右键导入刚刚创建的项目,创建的项目中一般默认有【src/main/java】,若是没有需要手动创建【src/main/java】、【src/main/resources】、【src/test/java】文件夹

  项目目录结构如下:

  

  配置pom.xml引用jar包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.osgc</groupId>
  <artifactId>MobileProducts</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>MobileProducts Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
    <spring.version>4.1.3.RELEASE</spring.version>
    <mybatis.version>3.2.6</mybatis.version>
    <slf4j.version>1.7.25</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
    <ojdbc.version>1.0.0</ojdbc.version>
  </properties>

<dependencies> <!-- spring依赖的jar包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- oracle数据库所需jar包 --> <dependency> <groupId>ojdbc6</groupId> <artifactId>ojdbc6</artifactId> <version>${ojdbc.version}</version> </dependency> <!-- 数据库连接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!-- data Source数据源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency> <!-- json格式化jar包 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.6</version> </dependency> <!-- 日志所需jar包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>org.logback-extensions</groupId> <artifactId>logback-ext-spring</artifactId> <version>0.1.1</version> </dependency> <!-- mybatis的依赖包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatis/spring包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- servlet3.0核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.2-b01</version> </dependency> <!-- jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 单元测试依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>MobileProducts</finalName> <plugins> <plugin> <groupId>org.eclipse.jerry</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.2.v20140723</version> </plugin> </plugins> </build> </project>

  通过mybatis自动生成代码:

    (1)下载需要的文件及jar包

      [mybatis-generator]

      

    (2)配置generatorConfig.xml文件

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE generatorConfiguration  
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  
<generatorConfiguration>  
   <!-- 数据库驱动-->  
    <classPathEntry  location="ojdbc6-1.0.0.jar"/>  
    <context id="DB2Tables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>  
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->  
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  
        <!--数据库链接URL,用户名、密码  这里使用的是oracle数据库-->  
        <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:osgc" userId="osgc" password="osgc">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  
        <!-- 生成模型的包名和位置-->  
        <javaModelGenerator targetPackage="com.osgc.web.bean.goods" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  
        <!-- 生成映射文件的包名和位置-->  
        <sqlMapGenerator targetPackage="com.osgc.web.mapping.goods" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
        </sqlMapGenerator>  
        <!-- 生成DAO的包名和位置-->  
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.osgc.web.basedao.goods" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
        </javaClientGenerator>  
        <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->  
        <table tableName="bs_goods" domainObjectName="Goods" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
        <table tableName="bs_goodspack" domainObjectName="GoodsPack" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>  
</generatorConfiguration>  

    (3)双击运行【mybatis自动生成类命令.bat】文件即可,运行成功就可以在src目录下找到生成的文件,每一个数据库表就会对应三个文件(实体类、接口、配置文件)

     

  生成代码后的目录结构

  

  2).Spring与Mybatis整合

    添加以下配置文件

    

    ojdbc.properties

ojdbc_driverClassName =oracle.jdbc.driver.OracleDriver
ojdbc_url=jdbc:oracle:thin:@127.0.0.1:1521:osgc
ojdbc_username=osgc
ojdbc_password=osgc

    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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- 1.配置jdbc文件 -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations" value="classpath:ojdbc.properties"/>
    </bean>

    <!-- 2.扫描的包路径,这里不扫描被@Controller注解的类 --><!--使用<context:component-scan/> 可以不在配置<context:annotation-config/> -->
    <context:component-scan base-package="com.osgc.web">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <import resource="classpath:spring-mybatis.xml" />

</beans>

    spring-mybatis.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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
   
   <!-- 配置数据源 -->
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <!-- 基本属性 url、user、password-->
    <property name="driverClassName" value="${ojdbc_driverClassName}"/>
    <property name="url" value="${ojdbc_url}"/>
    <property name="username" value="${ojdbc_username}"/>
    <property name="password" value="${ojdbc_password}"/>
    
    <!-- 配置初始化大小、最大、最小 -->
    <property name="initialSize" value="10"/>
    <property name="minIdle" value="10"/>
    <property name="maxActive" value="50"/>
    
    <!-- 配置获取连接等待超时时间  单位:毫秒 -->
    <property name="maxWait" value="60000"/>
    <!-- 配置检测间隔,检测需要关闭的空闲连接 单位:毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    
    <!-- 配置一个连接在连接池中的最小生存时间 单位:毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="300000"/>
    
    <property name="validationQuery" value="SELECT 'x'" />
    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />
    
    <!-- 打开PSCache,并且指定每个连接上PSCache的大小  如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。-->
    <property name="poolPreparedStatements" value="true" />
    <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
    
    <!-- 配置监控统计拦截的filters -->
    <property name="filters" value="wall,stat" />
   </bean>
   
   <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --> 
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <property name="dataSource" ref="dataSource"/>
       <!-- 自动扫描mapping.xml文件 -->
       <property name="mapperLocations" value="classpath*:com/osgc/web/mapping/**/*.xml"/>
   </bean>
   
   <!-- DAO接口所在包名,Spring会自动查找其下的类,自动扫描了所有的XxxxMapper.xml对应的mapper接口文件,只要Mapper接口类和Mapper映射文件对应起来就可以了 -->
   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="basePackage" value="com.osgc.web.basedao.**"/>
       <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
   </bean>
   
   <!-- 配置事务管理器 -->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource" ref="dataSource"></property>
   </bean>
   
   <!-- 配置基于注解的声明式事物 -->
   <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

    logback.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 用于输出日志 log4j:LOG4J SLF4J -->
    <settings>  
        <setting name="logImpl" value="SLF4J"/>  
    </settings>  

    <!-- 此文件可以为空文件, 但是必须要有这文件 -->
    
    <!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, 
        typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, 
        databaseIdProvider?, mappers? -->
    <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- 4.0.0以后版本可以不设置该参数 -->
            <property name="dialect" value="oracle" />
            <!-- 该参数默认为false -->
            <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
            <!-- 和startPage中的pageNum效果一样 -->
            <property name="offsetAsPageNum" value="true" />
            <!-- 该参数默认为false -->
            <!-- 设置为true时,使用RowBounds分页会进行count查询 -->
            <property name="rowBoundsWithCount" value="true" />
            <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
            <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
            <property name="pageSizeZero" value="true" />
            <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
            <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
            <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<!--             <property name="reasonable" value="false" /> -->
            <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
            <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
            <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
            <!-- 不理解该含义的前提下,不要随便复制该配置 -->
<!--             <property name="params"    value="pageNum=pageHelperStart;pageSize=pageHelperRows;" /> -->
            <!-- 支持通过Mapper接口参数来传递分页参数 -->
            <property name="supportMethodsArguments" value="false" />
            <!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
            <property name="returnPageInfo" value="none" />
        </plugin>
    </plugins>
</configuration>

   测试配置是否成功

  IGoodsService.java

package com.osgc.web.service.goods;

import com.osgc.web.bean.goods.Goods;

public interface IGoodsService {
    public Goods selectByPrimaryKey(Long goodsid);
}

  GoodsService.java

package com.osgc.web.service.goods;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.osgc.web.basedao.goods.GoodsMapper;
import com.osgc.web.bean.goods.Goods;


@Service
@Transactional(rollbackFor=Exception.class)
public class GoodsService implements IGoodsService {
    
    @Autowired
    public GoodsMapper mapper ;

    @Override
    public Goods selectByPrimaryKey(Long goodsid) {
        return mapper.selectByPrimaryKey(goodsid);
    }
    
}

  GoodsServiceTest.java

package com.osgc.web.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.osgc.web.bean.goods.Goods;
import com.osgc.web.service.goods.IGoodsService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml"})
public class GoodsServiceTest {
    
    @Autowired
    public IGoodsService service;
    
    @Test
    public void getUserByIdTest(){
        Goods goods = service.selectByPrimaryKey(1L);
        System.out.println(goods.getGoodsname());
    }
    
}

  3).整合SpringMVC

    (1)springmvc相关配置需要编写再spring-mvc.xml文件中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  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-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    
   <!-- 扫描controller(controller层注入) -->
   <context:component-scan base-package="com.osgc.web.controller.**" use-default-filters="false">
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
   </context:component-scan>
   
   <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
       <!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
       <property name="favorPathExtension" value="true"/>
       <!-- 用于开启 /userinfo/123?format=json的支持 -->
       <property name="favorParameter" value="true"/>
       <property name="parameterName" value="format"/>
       
       <!-- 是否忽略 Appcept Header -->
       <property name="ignoreAcceptHeader" value="false"/>
       
       <property name="mediaTypes"><!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->
           <value>
               json=application/json
               xml=application/xml
               html=text/xml
           </value>
       </property>
       <!-- 默认的content type -->
       <property name="defaultContentType" value="text/html"/>
   </bean>
   
   <mvc:default-servlet-handler/>
   
   <!-- 对模型视图添加前后缀 -->
   <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
    
</beans>

      (2) 在web.xml中添加SpringMVC启动配置,编写jsp

       web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <display-name>MobileProducts</display-name>
  
  <!-- 读取spring配置文件 -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  
  <!-- String 字符集过滤器 -->
  <filter>
      <filter-name>StringEncodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      
      <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
      </init-param>
      <init-param>
          <param-name>forceEncoding</param-name>
          <param-value>true</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>StringEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- 添加日志监听器 -->
  <context-param>
      <param-name>logbackConfigLocation</param-name>
      <param-value>classpath:logback.xml</param-value>
  </context-param>
  <listener>
      <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
  </listener>
  
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- springMVC核心配置 -->
  <servlet>
      <servlet-name>dispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <!--spingMVC的配置路径 -->
          <param-value>classpath:spring-mvc.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  
  <!-- 拦截设置 -->
  <servlet-mapping>
      <servlet-name>dispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
</web-app>

      index.jsp

<%@ page contentType="text/html; charset=utf-8"%>
<!doctype html>
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

     (4)启动Tomcat测试,启动成功后,访问http://localhost:8080/MobileProducts/(其中8080为Tomcat的端口号),页面显示 "Hello World!" 就表示项目配置成功

  4).编写Controller及业务页面

    这里我考虑到了前后端分离,所以示例也是以前后端分离的方式编写的,页面通过ajax请求controller,controller 通过传入的参数goodsid 查询信息并返回页面

    @Controller和@RestController的区别:  

    如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。

    因此@RestController注解就相当于@Controller + @ResponseBody 联合使用

    GoodsController.java

package com.osgc.web.controller.goods;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
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.RestController;

import com.osgc.web.bean.goods.Goods;
import com.osgc.web.service.goods.IGoodsService;

@RestController
@RequestMapping(value="/goods")
public class GoodsController {

    @Autowired
    private IGoodsService service;
    
    @RequestMapping(value="/showname",method=RequestMethod.POST)
    public String showGoodsName(@RequestParam("goodsid") Long goodsid,HttpServletRequest request,Model model){
        System.out.println("showname");
        Goods goods = service.selectByPrimaryKey(goodsid);
        if(goods != null){
            System.out.println(goods.getGoodsname());
            return "{"name":""+goods.getGoodsname()+""}";
        }
        System.out.println("没有找到该商品!");return "error";
    }
    
}

      showName.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>showname</title>
<script type="text/javascript" src="../js/jquery.js"></script>
</head>
<body>
<h1>Welcome</h1><span id="goodsname"></span><h1>访问此页面</h1>
</body>

<script type="text/javascript">
$.post("http://127.0.0.1:8080/MobileProducts/goods/showname",{"goodsid":1},function(data){
    console.info(data);
    $("#goodsname").html(data.name)
});
</script>
</html>

      需要注意的是html页面的存放位置

   

  5).处理Controller返回数据中文乱码问题

    在spring-mvc.xml文件中加入以下信息即可

  <mvc:annotation-driven>
       <mvc:message-converters register-defaults="true">
           <bean class="org.springframework.http.converter.StringHttpMessageConverter">
               <property name="supportedMediaTypes">
                   <list>
                       <value>application/json;charset=utf-8</value>
                       <value>text/html;charset=utf-8</value>
                       <value>application/x-www-form-urlencoded</value>
                   </list>
               </property>
           </bean>
       </mvc:message-converters>
   </mvc:annotation-driven>

   至此,一个基于SSM框架的前后端分离的Web项目就搭建完毕了

4.解决前后端分离出现的跨域问题

  1).编写过滤器CorsFilter.java

package com.osgc.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.osgc.web.service.util.StringUtil;

/**
 * 跨域访问处理
 * 解决前后端分离架构中的跨域问题
 * @author 李芊芊
 *
 */
public class CorsFilter implements Filter {
    
    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(CorsFilter.class);

    @SuppressWarnings("unused")
    private String allowOrigin;
    private String allowMethods;
    private String allowCredentials;
    private String allowHeaders;
    private String exposeHeaders;
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        allowOrigin = filterConfig.getInitParameter("allowOrigin");
        allowMethods = filterConfig.getInitParameter("allowMethods");
        allowCredentials = filterConfig.getInitParameter("allowCredentials");
        allowHeaders = filterConfig.getInitParameter("allowHeaders");
        exposeHeaders = filterConfig.getInitParameter("exposeHeaders");
    }

    /** 
     * @description 通过CORS技术实现AJAX跨域访问,只要将CORS响应头写入response对象中即可  
     * @param req
     * @param res
     * @param chain
     * @throws IOException
     * @throws ServletException     
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)     
     */
    @Autowired
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;  
        HttpServletResponse response = (HttpServletResponse) res; 

        String currentOrigin = request.getHeader("Origin"); 
        response.setHeader("Access-Control-Allow-Origin", currentOrigin);  
        /**
         * Access-Control-Allow-Origin:允许访问的客户端域名,例如:http://web.xxx.com,若为*,则表示从任意域都能访问,即不做任何限制。
         * Access-Control-Allow-Methods:允许访问的方法名,多个方法名用逗号分割,例如:GET,POST,PUT,DELETE,OPTIONS。
         * Access-Control-Allow-Credentials:是否允许请求带有验证信息,若要获取客户端域下的cookie时,需要将其设置为true。
         * Access-Control-Allow-Headers:允许服务端访问的客户端请求头,多个请求头用逗号分割,例如:Content-Type。
         * Access-Control-Expose-Headers:允许客户端访问的服务端响应头,多个响应头用逗号分割。
         */
        
        if (StringUtil.isNullOrEmpty(allowMethods)) {  
            response.setHeader("Access-Control-Allow-Methods", allowMethods);  
        }  
        if (StringUtil.isNullOrEmpty(allowCredentials)) {  
            response.setHeader("Access-Control-Allow-Credentials", allowCredentials);  
        }  
        if (StringUtil.isNullOrEmpty(allowHeaders)) { 
            response.setHeader("Access-Control-Allow-Headers", allowHeaders);  
        }  
        if (StringUtil.isNullOrEmpty(exposeHeaders)) {  
            response.setHeader("Access-Control-Expose-Headers", exposeHeaders);  
        }  
        chain.doFilter(req, res);
        

    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

  2).在web.xml中加载过滤器,添加如下代码

<filter>
      <filter-name>corsFilter</filter-name>
      <filter-class>com.osgc.web.filter.CorsFilter</filter-class>
      <init-param>
          <param-name>allowOrigin</param-name>
          <param-value>*</param-value>
      </init-param>
      <init-param>
          <param-name>allowMethods</param-name>
          <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
      </init-param>
      <init-param>
          <param-name>allowCredentials</param-name>
          <param-value>true</param-value>
      </init-param>
      <init-param>
          <param-name>allowHeaders</param-name>
          <param-value>Content-Type</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>corsFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

至此,SSM三大框架整合已全部完成了

参考:SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)

源代码:https://download.csdn.net/download/qq_35965441/10976680

原文地址:https://www.cnblogs.com/circle-quan/p/10432400.html