springMVC笔记

第一章:三层架构和MVC

1. 三层架构

  1. 咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
  2. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
  3. 三层架构
    1. 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
    1. 业务层:处理公司具体的业务逻辑的
    1. 持久层:用来操作数据库的

2. MVC模型

  1. MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
  2. Model:数据模型,JavaBean的类,用来进行数据封装。
  3. View:指JSP、HTML用来展示数据给用户
  4. Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。

第二章:SpringMVC的入门案例

1. SpringMVC的概述

  1. 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架。
  2. Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
  3. 使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等。

2.快速入门

  1. 创建WEB工程,引入开发的jar包
    具体的坐标如下
 <!-- 版本锁定 -->
    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</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-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

  1. 配置核心的控制器(配置DispatcherServlet)

   <!-- SpringMVC的核心控制器:配置DispatcherServlet(请求分发器) -->
   <servlet>
       <servlet-name>dispatcherServlet</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!-- 配置Servlet的初始化参数,加载springmvc.xml的配置文件,创建spring容器 -->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc.xml</param-value>
       </init-param>
       <!-- 配置servlet启动时加载springmvc.xml对象,启动级别:1 -->
       <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
       <servlet-name>dispatcherServlet</servlet-name>
<!--        /:只匹配所有的请求,不会匹配jsp-->
<!--        /*:匹配所有请求,包括jsp页面-->
       <url-pattern>/</url-pattern>
   </servlet-mapping>
</web-app>
  1. 编写springmvc.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">
<!--启动tomcat就会加载springMVC.xml-->

<!--    处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--    处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!-- 配置视图解析器:模拟引擎 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--        前缀后缀-->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
<!--    BeanNameUrlHandlerMapping:bean-->
    <bean id="/hello" class="快速入门.Controller.HelloController"/>
</beans>
  1. 编写index.jsp和HelloController控制器类
//实现Controller接口,这个类就是控制器了
    public class HelloController implements Controller {
     //这是用ModelAndView返回的方式
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv=new ModelAndView();

        //业务代码
        String result="helloSpringMVC";
        mv.addObject("msg",result);
        //视图跳转
        mv.setViewName("hello");
        return mv;
    }
}
  1. hello.jsp
 <body>
  <h3>入门案例</h3>
  ${msg}
</body>

注意:代码正确的情况下,有时候可能出现404,排查步骤:
1、查看控制台输出,看一下是不是缺少什么jar包
2、如果jar包存在,显示无法输出,就在idea项目中,添加lib依赖。
3、重启tomcat既可解决

3.流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FL0Smc5i-1587223551227)(mvc流程.png)]

具体流程:

(1)首先浏览器发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;

(2)DispatcherServlet——>HandlerMapping,处理器映射器将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象;

(3)DispatcherServlet——>HandlerAdapter,处理器适配器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;

(4)HandlerAdapter——>调用处理器相应功能处理方法,并返回一个ModelAndView对象(包含模型数据、逻辑视图名);

(5)ModelAndView对象(Model部分是业务对象返回的模型数据,View部分为逻辑视图名)——> ViewResolver, 视图解析器将把逻辑视图名解析为具体的View;

(6)View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构;

(7)返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

4.入门案例中的组件分析

  1. 前端控制器(DispatcherServlet)
dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
  1. 处理器映射器(HandlerMapping)
处理器映射器有三种,三种可以共存,相互不影响,分别是BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping和ControllerClassNameHandlerMapping.
1、BeanNameUrlHandlerMapping:默认映射器,即使不配置,默认就使用这个来映射请求。
2、SimpleUrlHandlerMapping:该处理器映射器可以配置多个映射对应一个处理器.
3、ControllerClassNameHandlerMapping:该处理器映射器可以不用手动配置映射, 通过[类名.do]来访问对应的处理器.
  1. 处理器(Handler)
  2. 处理器适配器(HandlAdapter)
处理器适配器有两种,可以共存,分别是SimpleControllerHandlerAdapter和HttpRequestHandlerAdapter。
  1. 视图解析器(View Resolver)
  2. 视图(View)

SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。

5.注解使用

springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">

    <!--启动tomcat就会加载springMVC.xml-->
<!--    自动扫描包-->
    <context:component-scan base-package="annotation"/>
<!--让springMVC不处理静态资源:静态资源过滤-->
    <mvc:default-servlet-handler/>

<!--    支持mvc注解驱动-->
<!--        在spring中一般采用@RequestMapping注解来完成映射关系
            要想使注解生效,必须注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例,
            这两个实例分别在类级别和方法级别处理,
            而annotation-driven配置帮助我们自动完成上述两个实例的注入    -->

    <mvc:annotation-driven/>
<!--    注意:
<mvc:annotation-driven/>为我们注册了映射器和适配器!
<mvc:annotation-driven>会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean-->

    <!-- 3、配置视图解析器:模拟引擎 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--        前缀后缀-->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

Controller类

/**
 * 使用注解
 */
@Controller///这标签相当于实现Controller接口,就是控制类
public class annotationController {
    /**
     *  @RequestMapping("/annotation")可以放在类上,表示类所有方法都必须经过这个路径
     *  放在方法上,只表示这个方法经过这个路径
     * 作用:用于建立请求 URL 和处理请求方法之间的对应关系。代替了<bean id="/annotation" class="annotation.Controller.HelloController"/>
     */
    @RequestMapping("/annotation")
    public String annotation(Model model) {
        System.out.println("进入controller");

        //封装数据(model是往前端发送数据)
        model.addAttribute("msg","hello springMVC");

        return "annotation";//会被视图解析器处理
    }
}

注解案例的执行流程

1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
2. 开启了注解扫描,那么HelloController对象就会被创建
3. 从(Controller类)/annotation全路径发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
5. Tomcat服务器渲染页面,做出响应

@Controller注解

被这个注解的类中所有的方法,如果返回值是String类型,并且有具体页面可以跳转,那么就会被视图解析器解析。

注意:@RestController=@Controller+@ResponseBody

RequestMapping注解

1. RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
2. RequestMapping注解可以作用在方法和类上
1. 作用在类上:第一级的访问目录
2. 作用在方法上:第二级的访问目录
3. 细节:路径可以不编写 / 表示应用的根目录开始
4. 细节:${ pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /

注意:

当RequestMapping一样时,要加个父路径。如@RequestMapping("/t") 和 @RequestMapping("/A/t")  //A是父路径,以此来区分

RequestMapping的属性

1. path 指定请求路径的url
2. value value属性和path属性是一样的
3. mthod 指定该方法的请求方式
4. params 指定限制请求参数的条件
5. headers 发送的请求中必须包含的请求头

6、RESTFUL风格

原来的访问风格:/restful?a=1&b=2
restful风格:/restful/1/2

方法里有参数时加上注解@PathVariable。
@PathVariable:路径变量

 public String restful(@PathVariable int a, @PathVariable int b, Model model){//这里的a和b对应到@PathVariable注解的a和b。通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中

restful风格:访问方式:GET、POST、DELETE、PUT以及PATCH

@RequestMapping(value = "/restful/{a}/{b}",method = RequestMethod.GET)
@GetMapping("/restful/{a}/{b}")//与上面的一样,get方式提交数据

restful风格的URL优点

  1. 结构清晰
  2. 符合标准
  3. 易于理解
  4. 扩展方便
  5. RESTFUL在传参会更安全。

7、转发和重定向

可以不配置视图解析器
写法
转发:

//跳转到:annotation页面
    return "forward:/WEB-INF/jsp/annotation.jsp";//前面加个forward:
    //跳转到:annotation路径,不是页面
    return "forward:annotation";

重定向:

    return "redirect:/index.jsp";//前面加个redirect:

第三章:请求参数的绑定(模块params)

要求:提交表单的name和参数的名称是相同的
注意:如果加注解@RequestParam就可以不一样。加@RequestParam表示是从前端传来的参数。如果不加注解,则参数名必须和表单(前端)传来的参数名一样

支持的数据类型

  1. 基本数据类型和字符串类型
  2. 实体类型(JavaBean)
  3. 集合数据类型(List、map集合等)

注意:

  1. 区分大小写

  2. 实体类型(JavaBean)

    提交表单的name和JavaBean中的属性名称需要一致
    如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:
    address.name

  3. 给集合属性数据封装

  4. JSP页面编写方式:list[0].属性

请求参数中文乱码的解决(post提交可能出现中文乱码问题)

  1. 在web.xml中配置Spring提供的过滤器类
<!-- 配置过滤器,解决中文乱码的问题 ,放在前面才能起作用--> 
<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> 

日期转换格式
1.在bean中加注解,如@DateTimeFormat(pattern = “yyyy-MM-dd”)
2. 自定义类型转换器

  • 表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明
    Spring框架内部会默认进行数据类型转换。
  • 如果想自定义数据类型转换,可以实现Converter的接口
//自定义类型转换器
public class StringToDateConverter implements Converter<String, Date> {
    /**
     * 用于把 String 类型转成日期类型
     */
    @Override
    public Date convert(String source) {
        DateFormat format = null;
        try {
            if(StringUtils.isEmpty(source)) {
                throw new NullPointerException("请输入要转换的日期");
            }
            format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = format.parse(source);
            return date;
        } catch (Exception e) {
            throw new RuntimeException("输入日期有误");
        } 
    }
}
  • 注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
            <!-- 自己写的类型转换器 -->
                <bean class="params.StringToDateConverter"/>
            </set>
        </property>
    </bean>

    <mvc:annotation-driven conversion-service="conversionService"/><!--conversion-service="conversionService"是注册日期转换器-->

第四章:常用的注解

@RequestParam注解

作用:把请求中的指定名称的参数传递给控制器中的形参赋值(即使和bean的属性名不一样也能用)
属性
    value:请求参数中的名称
    required:请求参数中是否必须提供此参数,默认值是true,必须提供
    defaultValue:默认值

@PathVariable注解

作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
属性
    1. value:指定url中的占位符名称

@ResponseBody注解

作用:将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body去。
通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

第五章:json

json是一种字符串格式

要实现从JSON字符串转换为JavaScript对象,使用 JSON.parse() 方法:
要实现从JavaScript对象转换为JSON字符串,使用 JSON.stringify() 方法:

ResponseBody 响应 json数据

  • 使用JackSon,导入jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.3</version>
</dependency>
  • 配置SpringMVC配置
<!-- 扫描包 -->
<context:component-scan base-package="annotation,RestFul,重定向,params,Json"/>

<mvc:annotation-driven>
<!-- 解决乱码问题 -->
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="utf-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperBuilder">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

乱码问题

方法一:使用(produces = “application/json; charset=utf-8”):
方法二 使用RequestMappingHandlerAdapter:

    <!-- 解决@ResponseBody返回中文乱码,必须放在<mvc:annotation-driven>之前 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="writeAcceptCharset" value="false" /> <!--  用于避免响应头过大  -->
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/plain;charset=UTF-8</value>
                            <value>text/html;charset=UTF-8</value>
                            <value>applicaiton/javascript;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

例子

        //jackson
        ObjectMapper mapper = new ObjectMapper();//固定写法
        //创建一对象
        user user = new user(1,"麦","123");

        String string = mapper.writeValueAsString(user);

//        return user.toString();
        return string;//固定写法,返回json字符串
    }

附注: FastJson也是非常好用的

第六章:Ajax

  • 配置web.xml 和 springmvc的配置文件,复制上面案例的即可。 记得静态资源过滤和注解驱动配置上

    <mvc:default-servlet-handler />
    <mvc:annotation-driven />
    
  • 经常用到jquery,所以记住导入jquery包。
    导入jquery , 可以使用在线的CDN , 也可以下载导入

    <!-- 这里使用在线的CDN导入 -->
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    
  • ajax一般写法:

    <script>
      function a1(){
        $.post({
            url:"${pageContext.request.contextPath}/ajax/ajaxTest",
            data:{'name':$("#username").val()},//注意:name是后台的参数,username是前端的参数(id名)
            success:function (data) {
                //根据Controller类的方法传进来的值来判断颜色
                if (data=='ok'){
                    $("#userInfo").css("color","green");
                }else {
                    $("#userInfo").css("color","red");
                }
                $("#userInfo").html(data);
            }
        });
    }
    </script>
    
     用户名:<input type="text" id="username" onblur="a1()"/>
    <span id="userInfo"></span>
    
  • 后台

      public String ajaxTest(String name){
        String msg="";
        //模拟数据库中存在数据
        if (name!=null){
            if ("admin".equals(name)){
                msg="ok";
            }else {
                msg="用户名输入错误";
            }
        }   
         return msg; 
    

参考练习见模块Ajax

注意:前端的参数和后台参数需要对应。如://注意:name是后台的参数,username是前端的参数(id名)

第七章:拦截器(interceptor)

拦截器配置

    <mvc:interceptors>
        <mvc:interceptor>
<!--    /**:包括这个请求下面的所有请求都会被拦截-->
            <mvc:mapping path="/**"/>
            <bean class="interceptor.Config.myInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器需继承接口HandlerInterceptor

/**
 * 自定义的拦截器,需继承接口
 */
//继承HandlerInterceptor接口
public class myInterceptor implements HandlerInterceptor {

    /**
     * 这三个方法是实现HandlerInterceptor接口的方法.不是强制必须实现的
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override//前置拦截器
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("=======处理前=========");
        //return true:执行下一个拦截器
        //return false:不执行下一个拦截器
        return false;
    }

    @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("=======清理=========");
    }
}

第八章:文件上传

Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。
而Spring MVC则提供了更简单的封装。
Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。
Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件

一、导入文件上传的jar包

<!--文件上传-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

二、配置bean:multipartResolver

<!--文件上传配置-->
<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
    <property name="defaultEncoding" value="utf-8"/>
    <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
    <property name="maxUploadSize" value="10485760"/>
    <property name="maxInMemorySize" value="40960"/>
</bean>

CommonsMultipartFile类 的 常用方法:

String getOriginalFilename():获取上传文件的原名
InputStream getInputStream():获取文件流
void transferTo(File dest):将上传文件保存到一个目录文件中

三、编写前端页面

<form action="/upload" enctype="multipart/form-data" method="post">
  <input type="file" name="file"/>
  <input type="submit" value="upload">
</form>

四、Controller

@Controller
public class FileController {
    //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
    //批量上传CommonsMultipartFile则为数组即可
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);

        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);

        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流

        //读取写出
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }
}

SSM练习模块

导入依赖

 <dependencies>
<!--    依赖:junit、数据库驱动、连接池、servlet、jsp、mybatis、mybatis-spring、spring-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
<!--    数据库驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.16</version>
    </dependency>
<!--    连接池-->
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <!--
     https://mvnrepository.com/artifact/org.mybatis/mybatis
    -->
<!--    mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.3</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.3</version>
    </dependency>
<!--    spring-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.3.RELEASE</version>
    </dependency>
<!--servlet、jsp-->
    <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.1-b03</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.8</version>
    </dependency>

<!--    前端网页需要引入jstl美化界面-->
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
  </dependencies>

Maven资源过滤设置

    <!--    mybatis:所有的maven项目都需要加进去这个文件,在父,子pom.xml里都需要加入一下代码   -->
    <!--在build中配置resources,来防止我们资源导出失败的问题-->
      <resources>
        <resource>
          <directory>src/main/resources</directory>
          <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
          </includes>
          <filtering>true</filtering>
        </resource>

        <resource>
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
          </includes>
          <filtering>true</filtering>
        </resource>
      </resources>

- mybatis-config.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核心配置文件 -->

<configuration>
<!--    不知道为什么用database.properties不行,所以不用了-->
    <!-- <properties resource="database.properties"/> -->

    <typeAliases>
        <package name="ssm_springMVC.POJO"/>
    </typeAliases>
    <!-- 在spring-dao配置 -->
<!--<environments default="development">-->
<!--    <environment id="development">-->
<!--        <transactionManager type="JDBC"/>-->
<!--        <dataSource type="POOLED">-->
<!--            <property name="driver" value="com.mysql.jdbc.Driver"/>-->
<!--            <property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>-->
<!--            <property name="username" value="root"/>-->
<!--            <property name="password" value="3105311"/>-->
<!--        </dataSource>-->
<!--    </environment>-->
<!--</environments>-->

<!--每一个Mapper.xml都需要在mybatis-config.xml核心配置文件中注册-->
<mappers>
    <mapper class="SSM1.dao.bookMapper"/>
</mappers>
</configuration>

- Spring整合Mybatis的相关的配置文件(spring-dao)

<?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"
       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">
<!--    Spring整合Mybatis的相关的配置文件; spring-dao.xml-->

<!--    不知道为什么用database.properties不行,所以不用了-->
    <!--关连数据库配置文件-->
    <!-- <context:property-placeholder location="classpath:database.properties"/> -->
    <!--    2、连接池
        dbcp:半自动化操作,不能自动连接
        C3P0:自动化操作(自动化的加载配置文件,并且可以自动设置到对象中)
        druid
        hikari
        -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="user" value="root"/>
        <property name="password" value="475035"/>
    </bean>
    <!--    3、sqlSessionFactory,这是mybatis工具类-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--        绑定mybatis的配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <!--    4、配置dao接口扫描包,动态实现dao接口可以注入到spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--        扫描dao包-->
        <property name="basePackage" value="SSM1.dao"/> 
    </bean>
</beans>

注意:没实现类时用动态扫描接口

  <!--    4、配置dao接口扫描包,动态实现dao接口可以注入到spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--        扫描dao包-->
        <property name="basePackage" value="SSM1.dao"/> 
    </bean>

  MapperScannerConfigurer类的作用:相当于核心配置文件的包注册-<package name="mapper"/>

- springMVC配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置SpringMVC -->
    <!--注解驱动-->
    <mvc:annotation-driven/>
<!--静态资源过滤-->
    <mvc:default-servlet-handler/>
<!--扫描包-->
    <context:component-scan base-package="ssm_springMVC.Controller"/>
<!--视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

- spring-service.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd" >
<!--1、扫描service下的包-->
    <context:component-scan base-package="ssm_springMVC.service"/>
<!--    2、将我们所有业务类注入到spring,可以通过配置或者注解实现-->
    <bean id="bookServiceImpl" class="ssm_springMVC.service.bookServiceImpl">
        <property name="bookMapper" ref="bookMapper"/>
    </bean>
<!--   3、 声明式事务管理-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--      4、  注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

- 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd" >
<!-- 将dao、service和mvc全部导进到spring核心配置文件     -->
    <import resource="spring_dao.xml"/>
    <import resource="spring_service.xml"/>
    <import resource="spring_mvc.xml"/>
    
</beans>

SSM整合:Mybatis

实现图书查询管理功能

- book——(实体bean)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class book {
    private int id;
    private String name;
    private int counts;
    private String detail;
}

- bookMapper接口

public interface bookMapper {
    //增加
    int addBook(book book);
    //删除一本书
    int deleteBook(int id);
    //更新
    int updateBook(book book);
    //查询
    book queryBook(int id);
    //查询所有书
    List<book> queryAllBook();
}

- bookMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="bookMapper">
    <insert id="addBook" parameterType="book">
        insert into ssm.book (name, counts, detail) values (#{name},#{counts},#{detail});
    </insert>

    <delete id="deleteBook" parameterType="int">
        delete from ssm.book where id=#{id};
    </delete>

    <update id="updateBook" parameterType="book">
        update ssm.book set name=#{name},counts=#{counts},detail=#{detail}
        where id=#{id};
    </update>

    <select id="queryBook" parameterType="int">
        select * from ssm.book where id=#{id};
    </select>

    <select id="queryAllBook" resultType="book">
        select * from ssm.book;
</select>
</mapper>

- service层(和dao层相似内容)

- service接口

public interface bookService {
    //增加
    int addBook(book book);
    //删除一本书
    int deleteBook(int id);
    //更新
    int updateBook(book book);
    //查询
    book queryBook(int id);
    //查询所有书
    List<book> queryAllBook();
    //查询框功能
    book queryBookByName(String name);
}

- service实现类

public class bookServiceImpl implements bookService{
//    service调用dao层:组合dao
    private bookMapper bookMapper;

    public bookServiceImpl(SSM1.dao.bookMapper bookMapper) {
        this.bookMapper = bookMapper;
    }

    public void setBookMapper(SSM1.dao.bookMapper bookMapper) {
    }

    @Override
    public int addBook(book book) {
        System.out.println("增加书本");
        return bookMapper.addBook(book);
    }

    @Override
    public int deleteBook(int id) {
        System.out.println("减少书本");
        return bookMapper.deleteBook(id);
    }

    @Override
    public int updateBook(book book) {
        System.out.println("更新书本");
        return bookMapper.updateBook(book);
    }

    @Override
    public book queryBook(int id) {
        System.out.println("查询书本");
        return bookMapper.queryBook(id);
    }

    @Override
    public List<book> queryAllBook() {
        System.out.println("查询所有书本");
        return bookMapper.queryAllBook();
    }

    @Override
    public book queryBookByName(String name) {
        System.out.println("想查询什么书籍");
        return bookMapper.queryBookByName(name);

    }
}

整合springMVC

control层

@Controller
@RequestMapping("/book")
public class bookController {
    //Controller调service层
    @Autowired
    @Qualifier("bookServiceImpl")
    public bookService bookService;

    //查询全部书籍,并且返回前端书籍展示页面
    @RequestMapping("/allBook")
    public String list(Model model){
        List<book> books = bookService.queryAllBook();//bookService—>bookMapper——>book(由bookService一直找到book对象,操作到数据库)
        model.addAttribute("list",books);
        return "allBook";//跳转到allBook.jsp
    }

    /**
     * 前面带to字段的方法都是跳转页面的方法
     * @return
     */
    //跳转到增加书籍页面
    @RequestMapping("/toAddBook")//前端新增书籍按钮跳转到这个方法并返回addBook字符串
    public String toAddBook(){
        return "addBook";
    }//跳进addBook.jsp页面

    //增加书籍方法
    @RequestMapping("/addBook")
    public String addBook(book book){//addBook.jsp页面传来book数据
        System.out.println("addBook"+book);
        bookService.addBook(book);
        return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
    }

    //跳转到修改书籍页面,并附带要修改的书籍信息
    @RequestMapping("/toUpdateBook")
    public String toUpdateBook(int id,Model model){
        book queryBook = bookService.queryBook(id);//将要修改书本的id和其他信息传到model并返回updateBook页面
        model.addAttribute("QBook",queryBook);//返回book对象,query方法必须添加resultType="book"
        return "updateBook";
    }
    //修改书籍方法
    @RequestMapping("/updateBook")
    public String updateBook(book book){
        System.out.println("updateBook"+book);
        bookService.updateBook(book);//需要提交事务,否则修改无效
        return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
    }

    //前端删除按钮跳转到该方法实现删除功能
//    @RequestMapping("/toDeleteBook")
//    public String toDeleteBook(int id){
//        int deleteBook = bookService.deleteBook(id);
//        return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
//    }
    /**
     * restful风格实现delete
     * @param id
     * @return
     */
    @RequestMapping("/toDeleteBook/{id}")
    public String toDeleteBook(@PathVariable("id") int id){
        bookService.deleteBook(id);
        return "redirect:/book/allBook";//重定向到上面的allBook请求。达到方法复用
    }

    //查询功能
    @RequestMapping("/toQueryBook")
    public String toQueryBook(String queryBookName, Model model){
        book book = bookService.queryBookByName(queryBookName);

        List<book> list = new ArrayList<book>();
        list.add(book);

        //查询优化
        if (book==null){
            list= bookService.queryAllBook();
            model.addAttribute("error","未查到书籍");
        }

        model.addAttribute("list",list);//list到时候会在allBook遍历用到
//        return "redirect:/book/allBook";//不能重定向到上面的allBook请求。因为会重新查询所有书籍
        return "allBook";//只能转发,才能查询单一书籍
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值