首页 > 编程语言 > 详细

SpringMVC框架学习总结

时间:2021-03-29 17:35:35      阅读:18      评论:0      收藏:0      [点我收藏+]

title: SpringMVC学习总结
date: 2020-08-27 20:03:17
tags: springmvc


SpringMVC入门

Mybatis:优化了dao层,降低了java与dao层的耦合。

Spring:优化了service层,降低了java与service层的耦合。

SpringMVC:优化了servlet,降低了java与servlet层的耦合。

目前市场上MVC框架,有SpringMVC(主流MVC框架,是spring框架的一部分),还有struts 和 Jfinal。

技术分享图片

XML配置开发

  1. 编写springmvc配置文件取名为spring.xml,注册后端控制器(注意id写法格式)
配置文件的约束:
<?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:p="http://www.springframework.org/schema/p"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
  1. 编写跳转资源页面
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class MyController implements Controller {
    @Override
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
        //创建视图模型对象
        ModelAndView m = new ModelAndView();
        m.addObject("name","张三");//往视图模型中加入流转数据
        m.setViewName("index.jsp");//设置要跳转的页面
        return m;
    }
}
<?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:p="http://www.springframework.org/schema/p"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 <bean id="/myController" class="com.spring.controller.MyController"></bean>
</beans>
  1. web.xml中urlpattern配置问题
<?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">
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>    <!-- /: 代表所有的请求都经过中央调度器-->
    </servlet-mapping>
</web-app>
  1. 配置 静态资源放行
<?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:p="http://www.springframework.org/schema/p"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <bean id="/myController" class="com.spring.controller.MyController"></bean>
    <!--放行静态资源image,css,js-->
    <mvc:resources mapping="/image/**" location="/image/"/>  <!-- mapping="/image/**"是uri的路径,其中**表示放行image目录下所有的文件及子目录下的文件-->
</beans>

SpringMVC注解式开发

  1. 搭建环境
    • 后端控制器无需实现接口,添加相应注解
    • springmvc配置文件无需注册controller
    • springmvc配置文件中添加组件扫描器、注解驱动 <mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与 AnnotationMethodHandlerAdapter 两个bean,并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)等等。
在配置文件中加上下面:
<!-- 注册扫描器:作用是让注解被扫描 -->
<context:component-scan base-package="spring.control"></context:component-scan>
<!-- 配置注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
  1. 涉及常用注解

@Controller、@Scope 加载类上

@RequestMapping(类体上【命名空间】、方法上)、类上的@RequestMapping :限定范围的作用,限定在浏览器上访问的路径。

方法上的@RequestMapping :请求路径。

在类名@Controller下一行加:@Scope("prototype") //表示每次请求都会创建新的实例,去掉就不会了
package com.spring.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller    //加这个注解等同于:<bean id="/myController" class="com.spring.controller.MyController"/>,同时实现了接口
@Scope(value = "prototype") //原型模式
@RequestMapping("/user")   //类上面加了限定路径名,访问的时候/user/show
public class MyController{

    @RequestMapping("/show")   //在浏览器上请求处理的控制器方法,限定路径的访问名
    public ModelAndView show(){
        ModelAndView m = new ModelAndView();   //用视图模型对像作为数据载体
        m.addObject("name","曹操");
        m.setViewName("/index.jsp");
        return m;
    }
    @RequestMapping("/show2")
    public String show2(HttpServletRequest req, HttpServletResponse resp){  //内置对象,可以直接作为形式参数使用
        req.setAttribute("name","刘备");//req域作为数据的流转载体
        return "/index.jsp";//页面的跳转,如果在类上加了父路径名,这里在页面前加一个/表示访问起始从根路径开始
    }
}
  1. 处理器方法常用的内置参数(五类):
    • HttpServletRequest
    • HttpServletResponse
    • HttpSession
    • 用于承载数据的Model、Map
    • 请求中所携带的请求参数
@RequestMapping("/show2")
public String show2(HttpServletRequest req, HttpServletResponse resp){  //内置对象,可以直接作为形式参数使用
    req.setAttribute("name","刘备");//req域作为数据的流转载体
    return "/index.jsp";//页面的跳转,如果在类上加了父路径名,这里在页面前加一个/表示访问起始从根路径开始
}

@RequestMapping("/show3")
public String show3(HttpSession session, Map<String,String> map, Model model){
    session.setAttribute("name","赵飞燕");  //session域作为数据载体
    //使用Map作为数据载体
    map.put("city","长沙");
    map.put("province","湖南");
    model.addAttribute("phone","136789898798");
    return "/index.jsp";
}
  1. 接收请求参数

    4.1 逐个接收 (涉及注解@RequestParam)

    4.2 以对象形式整体接收

    4.3 域属性参数的接收

    4.4 数组或集合参数的接收

    4.5 restfull风格,传参(涉及注解@ PathVariable)

    4.6 接收json字符串(涉及注解@ResponseBody)

  2. 获取请求头中参数(涉及注解@RequestHeader)

package com.spring.controller;
import com.spring.pojo.User;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;

@Controller
public class LoginController {
    @RequestMapping("/login")
    public String login(HttpServletRequest req, HttpServletResponse resp){
        String uname = req.getParameter("uname");
        String pwd = req.getParameter("pwd");
        System.out.println(uname);
        System.out.println(pwd);
        return "success.jsp";
    }
    //逐个接收提交的数据
    @RequestMapping("/login2")
    public String login2(String uname,String pwd,String[]favor,String birthday){  //参数名字与表单中的name里面的值一致即可
        System.out.println(uname);
        System.out.println(pwd);
        for(String str:favor){
            System.out.println(str);
        }
        System.out.println(birthday);
        return "success.jsp";
    }
    //逐个接收提交的数据
    @RequestMapping("/login3")
    public String login3(String uname, String pwd, String[]favor,@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date birthday){  //@DateTimeFormat可以把提交字符串转成Date对象
        System.out.println(uname);
        System.out.println(pwd);
        for(String str:favor){
            System.out.println(str);
        }
        System.out.println(birthday);
        return "success.jsp";
    }
    @RequestMapping("/login4")
    public String login4(User user, HttpSession session){
        session.setAttribute("user",user);
        return "success.jsp";
    }
    @RequestMapping("/login5/{username}/{password}")  //{username}表示接收uri携带的数据,并取名为username
    public String login5(@PathVariable String username,@PathVariable String password){
        System.out.println(username);
        System.out.println(password);
        return "success.jsp";
    }
    @RequestMapping("/login6")
    @ResponseBody()  //加了这个注解之后返回的return变成了一个数据ResponseBody(响应体),而不是页面跳转
    public String login6(String name,String age){
        System.out.println(name);
        System.out.println(age);
        String json = "{‘name‘:‘"+name+"‘,‘age‘:‘"+age+"‘}";
        System.out.println(json);
//        return "success.jsp";//默认情况下return是跳转页面
        return json;
    }
}
  1. 解决jsp中路径的问题
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
    <base href="<%=basePath%>">
    <title>Title</title>
</head>
  1. 解决中文乱码问题

CharacterEncodeingFilter

<!--使用过滤器统一设置请求编码-->
<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>

controller中的方法设置响应编码

@RequestMapping(value = "/login",produces = "text/html;charset=utf-8")
  1. 处理器方法的返回值

    8.1 ModelAndView

    8.2 String

    8.3 void (使用场景:方法参数为HttpServletRequest和HttpServletResponse时获取用户提交数据时使用)

    8.4 Object(涉及注解@ResponseBody ,导入jackson相关的包)

package com.spring.controller;

import com.spring.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class TestController {
    @RequestMapping("/getMsg")
    public void getMsg(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        req.getRequestDispatcher("success.jsp").forward(req,resp);  //请求转发
        resp.sendRedirect("success.jsp");
    }

    @RequestMapping("/getObj")
    @ResponseBody
    public Object getObj(){
        User user= new User("赵飞燕","123456");
        return user;//需要依赖user返回的过程之中会转成json数据
    }
}
  1. 请求转发与重定向
package com.spring.controller;

import com.spring.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class TestController2 {
    @RequestMapping("/showPage")
    public String showPage(){
        return "forward:success.jsp"; //默认就是请求转发,forward:默认情况下可以省略
    }
    @RequestMapping("/showPage2")
    public String showPage2(){
        return "redirect:success.jsp"; //重定向,redirect:不能省略
    }
}

提高项目访问的安全性及统一管理

放在WEB-INF下

原理:

静态及jsp资源放在WEB-INF下,客户端不能直接访问,服务端才可以访问到,也就是说别人不能够串改你的代码。为了方便让Spring映射:就是配置文件上会带有对静态资源的配置信息。如果想在页面中直接访问其中的文件,必须通过视图解析器对要访问的文件进行相应映射才能访问。

@Controller
public class PageController {
   //动态实现控制器跳转到jsp文件
    @RequestMapping("/{page}")
    public String getPage(@PathVariable String page){
        return page;
    }
}

视图解析器(前缀、后缀)

<!-- jsp视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>  <!-- 前缀,jsp页面所在的路径 -->
        <property name="suffix" value=".jsp"></property>  <!-- 文件的后缀 -->
        <property name="order" value="1"></property>   <!--解析器的优先级,数字越小优先级越高-->
</bean>

<!-- html视图解析器 -->
<!-- 配置freeMarker的模板路径 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath">
                <value>/WEB-INF/html/</value>  <!--html文件的前缀-->
        </property>
        <property name="defaultEncoding">
                <value>utf-8</value>
        </property>
</bean>
<!-- 配置freeMarker视图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
        <property name="contentType" value="text/html; charset=utf-8"/>
        <property name="suffix" value=".html" />  <!--html文件的后缀-->
        <property name="order" value="0"/>  <!--解析器的优先级,数字越小优先级越高-->
</bean>

配置html的解析器需要先引入freemarker-2.3.28.jar

自定义SpringMVC的配置文件路径和文件名

在web.xml的中央调度器中配置
<servlet>
    <servlet-name>dispatcherServlet</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>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>    <!-- /: 代表所有的请求都经过中央调度器-->
</servlet-mapping>

文件上传

表单提交媒体类型enctype="multipart/form-data"

在springmvc配置文件中添加:

<!-- 注册文件上传解析器 ,id名字对应DispatcherServlet的源码中的属性multipartResolver-->	
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 配置属性,解决文件中文名乱码的问题 -->
	<property name="defaultEncoding" value="utf-8"></property>
</bean>	

Jsp页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<html>
<head>
    <base href="<%=basePath%>">
    <title>Title</title>
</head>
<body>
    <form action="upload" method="post" enctype="multipart/form-data"><%--文件上传属于多媒体数据,加这个数据描述enctype--%>
        文件:<input type="file" name="files"/><br/>
        <input type="submit" value="上传">
    </form>
</body>
</html>

Controller层的代码

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;

@Controller
public class FileController {
    @RequestMapping("/upload")
    public String upload(MultipartFile files) throws IOException {  //这里的参数名得和前端提交的name值一致
        String fileName = files.getOriginalFilename();//获取上传过来的文件名
        File path = new File("d:/");//指定文件存储的位置
        File file= new File(path,fileName);
        files.transferTo(file);//进行数据的传输
        return "upload_success"; //不用写后缀了,由页面控制器转到视图解析器里面拼接前缀和后缀
    }
}

文件下载

返回值类型: ResponseEntity<byte[]>

以附件的形式下载:

headers.add("Content-Disposition", "attachment;filename="+fileName);

@RequestMapping("/download")
    public ResponseEntity<byte[]> download() throws IOException {
        File file = new File("d:/idea使用.docx");//指定要下载的文件路径及文件名
        FileInputStream in = new FileInputStream(file);
        byte[] b = new byte[in.available()];//创建了一个byte数组和文件一样大
        in.read(b);//把文件中的数据全部放入byte数组中
        String fileName = file.getName();
        HttpHeaders headers = new HttpHeaders();
        //用附件的形式接收下载的文件
        headers.add("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));//解决文件中文名不识别的问题
        //创建响应的状态码
        HttpStatus status = HttpStatus.OK;//代表响应码200,表示连接建立成功,可以传输数据
        ResponseEntity<byte[]> entity= new ResponseEntity<byte[]>(b,headers,status);
        return entity;
    }

Spring和SpringMVC父子容器关系

在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系,目前最常见的一种场景就是在一个项目中引入Spring和SpringMVC这两个框架,那么它其实就是两个容器,Spring是父容器,SpringMVC是其子容器,并且在Spring父容器中注册的Bean对于SpringMVC容器中是可见的,而在SpringMVC容器中注册的Bean对于Spring父容器中是不可见的,也就是子容器可以看见父容器中的注册的Bean,反之就不行。

SSM整合开发

环境搭建(jar包及web.xml)

<!-- 上下文参数:加载所有的配置文件 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext-*.xml</param-value>   <!-- 加载src下所有的application-*.xml的配置文件 -->
	</context-param>
	<!-- 注册监听器,监听ServletContext对象,让其tomcat启动时创建Spring对象 -->
	<listener>
		<display-name>ContextLoaderListener</display-name>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

使用开源的数据库连接池

  1. DBCP的使用
    • 引入jar包
    • l 配置DBCP连接池
<!-- 配置DCPC的连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
	<!-- 属性注入 -->
	<property name="driverClassName" value="${jdbc.driver}"></property>
	<property name="username" value="${jdbc.username}"></property>
	<property name="password" value="${jdbc.password}"></property>
	<property name="url" value="${jdbc.url}" />
</bean>

C3P0的使用

  • 引入c3p0连接池jar包
  • 配置c3p0连接池
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="jdbcUrl" value="${jdbc.url}"></property>
	<property name="user" value="${jdbc.username}"></property>
	<property name="password" value="${jdbc.password}"></property>
	<property name="driverClass" value="${jdbc.driver}"></property>
</bean>

c3p0与dbcp区别

  1. 对数据连接的处理方式不同:
  • c3p0 提供最大空闲时间,当连接超过最大空闲连接时间时,当前连接就会被断掉。

  • dbcp 提供最大连接数,当连接数超过最大连接数时,所有连接都会被断开。

  1. 有无自动回收空闲连接的功能 :
  • c3p0 有,效率相对较低

  • dbcp 没有,需要自己手动释放资源,dbcp效率相对较高

SpringMVC框架学习总结

原文:https://www.cnblogs.com/fufengxi/p/14592726.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!