SpringMvc基础及SSM整合(内含spring-tx整合)

SpringMvc

pom文件最好配置如下:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

<!--静态资源导出问题-->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

最基本使用

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置DispatcherServlet 请求分发器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>

    <!--/ 匹配所有请求 但不包含.jsp-->
    <!--/* 匹配所有请求 包含.jsp-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

springmvc.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--处理器-->
    <bean id="/hello" class="com.nxj.controller.HelloController"/>
</beans>

controller

package com.nxj.controller;

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

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

/**
 * @author ningxinjie
 * @date 2021/2/9
 */
public class HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "springMvc数据传输...");
        mv.setViewName("test");
        return mv;
    }
}

jsp

<%--
  Created by IntelliJ IDEA.
  User: nxj
  Date: 2021/2/9
  Time: 12:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    我是test页面
    ${msg}
</body>
</html>

正常开发使用

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置DispatcherServlet 请求分发器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>

    <!--/ 匹配所有请求 但不包含.jsp-->
    <!--/* 匹配所有请求 包含.jsp-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--扫描包,让指定包下的注解生效,由IOC容器统一管理-->
    <context:component-scan base-package="com.nxj.controller"/>
    <!--让Spring MVC不处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--
        在Spring中一般采用@RequestMapping注解来完成映射关系
        要向使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter实例
        分别是类级别与方法级别的处理
        而annotation-driven配置就是帮助我们完成上面两个实例的注入
    -->
    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

controller

package com.nxj.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author ningxinjie
 * @date 2021/2/9
 */
@Controller
public class HelloController {

    // 响应到浏览器
    @RequestMapping("/hi")
    @ResponseBody
    public String hello(){
        return "hello SpringMvc";
    }

    // 跳转到/WEB-INF/jsp/hello.jsp页面 【前缀和后缀是由视图解析器添加的】
    @RequestMapping("/hel")
    public String helloPage(Model model){
        model.addAttribute("msg", "芳芳~!~");
        return "hello";
    }

    // 存储数据并跳转到/WEB-INF/jsp/hello.jsp页面
    @RequestMapping("/hello")
    public ModelAndView modelAndView(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "hello 啊~!");
        mv.setViewName("hello");
        return mv;
    }
}

Restful风格

@PathVariable

@Controller
@RequestMapping("/restful")
public class RestfulTestController {
    @RequestMapping("/t2/{num1}/{num2}")
    public String test01(@PathVariable("num1") int num1, @PathVariable("num2") int num2, Model model){
        model.addAttribute("msg", num1 + num2);
        return "test";
    }
}

转发与重定向

方式一:原生Servlet方式

使用HttpServletRequest与HttpServletResponse参数接收

@RequestMapping("/t3")
public void testForwardAndRedirect(HttpServletRequest request, HttpServletResponse response){
    try {
        // request.getRequestDispatcher("index.jsp").forward(request,response);
        request.getRequestDispatcher("WEB-INF/jsp/test2.jsp").forward(request,response);

    } catch (ServletException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

方式二:推荐使用

  1. 转发:

    1.     @RequestMapping("/t1")
          public String test01(){
              // 走视图解析器
              return "test";
          }
      
    2. @RequestMapping("/t4")
      public String testForwardAndRedirect02(){
           // return "redirect:/WEB-INF/jsp/test2.jsp"; //WEN-INF下的内部资源重定向是无法访问的
           return "forward:index.jsp";
      }
      
  2. 重定向

    1. @RequestMapping("/t4")
      public String testForwardAndRedirect02(){
           return "redirect:index.jsp";
      }
      

乱码处理

<!--配置SpringMvc的乱码过滤-->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <!--/*匹配所有-->
    <url-pattern>/*</url-pattern>
</filter-mapping>

Json测试

请求乱码解决等

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.nxj.controller"/>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven>
        <!--mvc配置统一请求乱码解决问题-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">

                <property name="defaultCharset" value="utf-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
    @ResponseBody
    @RequestMapping(value = "/json"/*,produces ="application/json;charset=UTF-8"*/) // 通过produces属性设置编码
    public String jsonStringTest(){
        try {
            UserBasic userBasic = new UserBasic("宁新杰" ,"23");
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonStr = objectMapper.writeValueAsString(userBasic);
            return jsonStr;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

SSM整合

pojo

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer bookId;
    private String bookName;
    private Integer bookCount;
    private String bookDescribe;
}

Dao层

/**
 * @author ningxinjie
 * @date 2021/2/11
 */
public interface BookDao {
    // 查询全部书籍
    List<Book> queryAllBooks();

    // 根据id查询书籍
    Book queryBookById(Integer id);

    // 根据条件查询书籍
    List<Book> queryBookByCondition(Book book);

    // 增加一本书
    int addBook(Book book);

    // 通过id更新书
    int updateBookById(Book book);

    // 删除一本书
    int delBookById(Integer id);
}

manager

@Component("bookManager")
public class BookManager {

    @Resource
    private BookDao bookDao;

    @Transactional
    public void insertTransactionalTest(){
        System.out.println("BookManager调用开始");
        bookDao.addBook(new Book(1,"我测试",5,"我随时随地"));
        System.out.println("BookManager调用结束");
        int a = 1 / 0;
        System.out.println("异常。,,。,");
    }
}

BookService

public interface BookService {
    void doServiceTest();
}

BookServiceImpl

@Service("bookService")
public class BookServiceImpl implements BookService {

    @Resource
    private BookManager bookManager;

    @Override
    public void doServiceTest() {
        System.out.println("service调用开始");
        bookManager.insertTransactionalTest();
        System.out.println("service调用结束");
    }
}

controller

@Controller
@RequestMapping("/book")
public class BookController {

    @Resource
    @Qualifier("bookService")
    private BookService bookService;

    @RequestMapping("/test")
    public String test(){
        System.out.println("test方法执行开始...");
        bookService.doServiceTest();
        System.out.println("test方法执行完毕!");
        return "test";
    }
}

创建一个mybatis的配置文件**(虽然好多属性可以在spring配置文件中配置,保留着)

<?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>
    <!--
    <typeAliases>
        <typeAlias type="com.nxj.pojo.Book" alias="book"/>
    </typeAliases>
-->

    <!--    <mappers>-->
    <!--        <mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
    <!--    </mappers>-->
</configuration>

applicationContext.xml

<context:property-placeholder location="classpath:db.properties"/>
<!--扫描com.nxj包下的组件,我们通过注解加入到容器中,controller标注的由springmvc接管-->
<context:component-scan base-package="com.nxj">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<import resource="spring-jdbc.xml"/>
<import resource="spring-dao.xml"/>
<import resource="spring-mvc.xml"/>
<import resource="spring-tx.xml"/>

spring-jdbc.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--使用spring的jdbc管理数据库是可以的-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
    </bean>
    <!--使用c3p0数据库连接池管理也是可以的-->
    <!--com.mchange.v2.c3p0.DriverManagerDataSource-->
    <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
    </bean>
</beans>

spring-dao.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">



    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource2"/>
        <!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="mapUnderscoreToCamelCase" value="true"/>
            </bean>
        </property>
    </bean>

<!-- 我一般使用的是这个,需要一个个配置
    <bean id="bookDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.nxj.dao.BookDao"/>
        <property name="sqlSessionFactory" ref="sessionFactory"/>
    </bean>
-->

    <!--使用这种方式,扫描包下的所有的接口-->
    <!--配置dao接口扫描包,动态的实现了Dao接口可以注入到Spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
        <!--要扫描的dao包-->
        <property name="basePackage" value="com.nxj.dao"/>
    </bean>

</beans>

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--扫描包-->
    <context:component-scan base-package="com.nxj.controller"/>
    <!--静态资源过滤-->
    <mvc:default-servlet-handler/>
    <!--注解驱动-->
    <mvc:annotation-driven>
        <!--mvc配置统一请求乱码解决问题-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">

                <property name="defaultCharset" value="utf-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
    <!--拦截器设置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--'/**' 是拦截所有请求-->
            <!--'/*' 则是拦截/下的请求(单级别的 /a/b则不行)-->
            <mvc:mapping path="/**"/>
            <bean class="com.nxj.config.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

spring-tx.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:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    <!--Spring事务Aop配置组件-->
    <bean class="org.springframework.transaction.annotation.TransactionManagementConfigurationSelector"/>

    <!--需要事务管理器 TransactionManager 我选了其中的一个实现类-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource2"/>
        <property name="rollbackOnCommitFailure" value="true" />
    </bean>

    <!--标注事务(标注后才能生效) -->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
</beans>

拦截器

就是Aop,和我们使用切入是一样的,它是springmvc特有的,处理controller请求的

public class MyInterceptor implements HandlerInterceptor {
    // return true则放行
    // return false则拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截前验证");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("处理后");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("最后方法");
    }
}
   <!--拦截器设置-->
   <mvc:interceptors>
       <mvc:interceptor>
           <!--'/**' 是拦截所有请求-->
           <!--'/*' 则是拦截/下的请求(单级别的 /a/b则不行)-->
           <mvc:mapping path="/**"/>
           <bean class="com.nxj.config.MyInterceptor"/>
       </mvc:interceptor>
   </mvc:interceptors>
拦截前验证
test方法执行开始...
处理后
最后方法
原文地址:https://www.cnblogs.com/ningxinjie/p/14397793.html