SpringMVC使用详解

1、MVC和SpringMVC

1.1、MVC是什么

MVC:M Model V View C Controller 模型(javabean) 视图(jsp/img) 控制器(serlvet/action)
存在的目的:把模型渲染视图,即时把模型更新到视图中

在这里插入图片描述

1.2、什么是SpringMVC

Spring MVC是基于MVC模式的一个框架,它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化、等等),而且使用简单,与spring无缝集成。

2、SpringMVC的入门程序

2.1、HelloWorld

(1)导入资源包:
在这里插入图片描述

(2)在classpath下添加配置文件(application.xml)

(3)编写核心类,实现接口org.springframework.web.servlet.mvc.Controller,配置到配置文件中

核心类代码:

public class HelloWorldController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
       System.out.println("HelloWorldController.handleRequest()");
       String user = request.getParameter("user");//获得URL传递的参数
       request.setAttribute("key", "你好");
       request.getRequestDispatcher("hello.jsp").forward(request, response);//回写数据
        return null;
    }
}

配置文件:

<!--name:对应的是前端访问的人口 -->
<bean name="/hello"  class="com.it520.controller.HelloWorldController"></bean>

(4)web.xml中配置前端控制器和加载配置文件的位置

​ 默认加载路径WEB-INF文件夹下名为:-servlet.xml的文件

  <servlet>
     <!--配置前端控制器-->
    <servlet-name>sprinMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
     <!--配置加载配置文件的位置-->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:application.xml</param-value>  
    </init-param>
  </servlet>
  <servlet-mapping>
     <servlet-name>sprinMVC</servlet-name>
     <url-pattern>/</url-pattern>  
  </servlet-mapping>

(5)部署、启动服务器和访问

2.2、设置Serlvet的启动时机

Serlvet默认在第一次访问的时候启动,去加载项目,如果项目很大会造成第一次访问时间太长。

为了解决第一次访问很慢的问题,我们可以通过配置load-on-startup属性来设置Serlvet的启动时机。

web.xml中的配置如下:

<!-- 数值越小,启动优先级越高 -->
    <load-on-startup>1</load-on-startup>

2.3、通过ModelAndView的回写值

上述的核心类中是通过HttpServletRequest和HttpServletResponse的方式来向客户端回写数值,SpringMVC通过了基于ModelAndView的回写值得方式,代码如下:

public class HelloWorldController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
       System.out.println("HelloWorldController.handleRequest()");
       String user = request.getParameter("user");
//       request.setAttribute("key", "你好");
//       request.getRequestDispatcher("hello.jsp").forward(request, response);
       ModelAndView mv = new ModelAndView();
       mv.addObject("key", "你好ModelAndView");
       mv.setViewName("hello.jsp");
        return mv;
    }
}

hello.jsp

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>回写数据</title>
</head>
<body>
${key}
</body>
</html>

3、SpringMVC的执行流程

在这里插入图片描述

HanderMapping 请求映射处理器:
作用:根据不同的请求选择最合适的处理器(自己编写的控制器),请求映射处理器可以配置多个,谁最先匹配就执行谁。

HandlerAdapter 处理器适配:
作用: 支持多种类型的处理器,如何来执行"处理器(控制器)

4、基于全注解的方式使用SpringMVC

步骤

(1)在application.xml中开启注解扫描

(2)在application.xml中添加对springmvc驱动支持

<!-- 开启注解扫描 -->
<context:component-scan base-package="com.it520.controller"></context:component-scan>
<!-- 添加对springmvc驱动支持 -->
<mvc:annotation-driven/>

(3)导入Spring中的AOP的包

(4)编写核心类

​ 编写核心类,在类上添加@Controller
​ 在方法上添加注解@RequestMapping("/method") ,方法名随意,方法参数随意,自动注入,注意:要么参数列表中有response,要么就返回modelANdView

@Controller
public class AnnoSpringMVC {
    
    @RequestMapping("/method")
    public ModelAndView method() {
        System.out.println("======");
        ModelAndView mv = new ModelAndView();
        mv.addObject("key", "你好anno");
        mv.setViewName("hello.jsp");
        return mv;
    }
}

(5)支持对静态资源的处理(dispatcherSerlvet把静态资源处理掉了)

<mvc:default-servlet-handler/>

5、传参方式

使用一个简单的前端页面测试,input.jsp,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户注册</title>
</head>
<body>
<fieldset>
	<legend>用户注册1</legend>
	<form action="/springMVC/value1" method="post">
		<table>
			<tr>
				<td>用户名</td>
				<td><input type="text" name="userName"></td>
			</tr>
			<tr>
				<td>密码</td>
				<td><input type="text" name="password"></td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="提交"></td>
			</tr>
		</table>
	</form>
</fieldset>

在这里插入图片描述

5.1、在方法参数上带上request

@RequestMapping("/value1")
public ModelAndView value1(HttpServletRequest request) {
    System.out.println("ValueDemo.value1()");
    String username = request.getParameter("userName");
    String password = request.getParameter("password");
    User u = new User(username,password);
    System.out.println(u.toString());
    ModelAndView mv = new ModelAndView("input.jsp");
    return mv;
}

5.2、前台参数的key和后台方法的形参名对应就能自动注入

@RequestMapping("/value2")
    public ModelAndView value2(String userName,String password){
        System.out.println("ValueDemo.value2()");
        User u = new User(userName,password);
        System.out.println(u.toString());
        ModelAndView mv = new ModelAndView("input.jsp");
        return mv;
    }

将第一个参数名改成name

//当前台参数和后台方法的形参不一致时可以通过@RequestParam来改变传入的形参
public ModelAndView value3(@RequestParam("name") String userName ,String password) {
    System.out.println("ValueDemo.value3()");
    User u = new User(userName,password);
    System.out.println(u.toString());
    ModelAndView mv = new ModelAndView("input.jsp");
    return mv;
}

5.3、对象传参方式(对象类中必须要有无参的构造方法)

@RequestMapping("/value4")
public ModelAndView value4(User u) {
    System.out.println("ValueDemo.value4()");
    System.out.println(u.toString());
    ModelAndView mv = new ModelAndView("input.jsp");
    return mv;  
}

5.4、地址栏传参 localhost/delete/5

    @RequestMapping("/delete/{id}")
    public ModelAndView value5(@PathVariable("id") Long id){
        System.out.println("delete");
        System.out.println(id);
        ModelAndView mv = new ModelAndView("input.jsp");
        return mv;
    }

5.5、配置中文乱码过滤器

在web.xml中增加如下配置

  <filter>
    <filter-name>hi</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>hi</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>

6、传值方式

后续的回显数据提供data.jsp回传到前端,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>数据回显</title>
</head>
<body>
${msg }<br>
${string }<br>
${date }<br>
${user }
</body>
</html>

6.1、原始方式 request.setAttribute("","");

@RequestMapping("/data1")
public ModelAndView data1(HttpServletRequest request) {
    request.setAttribute("msg", "今天你好");
    ModelAndView mv =  new ModelAndView("data.jsp");
    return mv;
}

6.2、通过modelAndView的addObject()

@RequestMapping("/data2")
public ModelAndView data2() {
    ModelAndView mv = new ModelAndView("data.jsp");
    mv.addObject("msg","今天天气不错");
    mv.addObject("明天天气不错");//如果只传入值,默认key为数据类型,全小写
    mv.addObject(new Date());
    mv.addObject(new User("xiaoming","232154"));
    mv.addObject(new User("xiaomei","12154"));//后面的值会覆盖前面的值
    return mv;
}

6.3、直接返回对象,需要配置视图解析器

在application.xml中配置回显数据的前缀和后缀

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property><!--设置回显数据路径的前缀,并在WEB-INF下创建一个view文件夹 -->
<property name="suffix" value=".jsp"></property><!--设置回显数据路径的后缀  -->
</bean>
@RequestMapping("/data3")
@ModelAttribute("myUser")//通过@ModelAttribute注解来设置回显数据的形参
public User data3() {
    return new User("xiaoming","123");//响应视图为(前缀+请求路径+后缀)及WEB-INF/view/data3.jsp
}

在WEB-INF/view/文件夹下添加data3.jsp的代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${myUser }
</body>
</html>

6.4、返回String,可以通过Model传值

@RequestMapping("/data4")
public String data4(Model ml){
    ml.addAttribute("msg", "jttcbc");
    return "show";//响应视图为(前缀+返回值+后缀)及WEB-INF/view/show.jsp
}

在WEB-INF/view/文件夹下添加show.jsp的代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg }
</body>
</html>

6.5、取消前缀和后缀forward和redirect

forward叫转发,redirect叫做重定向,地址栏,数据共享,应用场景,效率,本质,次数上都有些许区别,具体的区别可参考博客:https://blog.csdn.net/weixin_37766296/article/details/80375106

@RequestMapping("/data5")
public String data5(Model ml){
    ml.addAttribute("msg", "jttcbc5");
    return "forward:hello.jsp";//直接访问根目录下的hello.jsp
}
@RequestMapping("/data6")
public String data6(Model ml){
    ml.addAttribute("msg", "jttcbc6");
    return "redirect:hello.jsp";//直接访问根目录下的hello.jsp
}
}

7、文件上传

(1)编写文件上传的前台页面upload.jsp,注意表单 类型:enctype=“multipart/form-data”

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
</head>
<body>
<fieldset>
<legend>文件上传</legend>
    <form action="/springMVC/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file"><br>
        <input type="submit" name ="提交"> 
    </form>
</fieldset>
</body>
</html>

(2)在application.xml中配置上传解析器

<!--上传解析器  id为固定名称 multipartResolver-->
<bean id="multipartResolver" 
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize">
        <value>1048576</value>
    </property>
</bean>

(3)编写上传类;

@RequestMapping("/upload")
public String upload(MultipartFile file) {
    System.out.println(file.getContentType());//文件类型
    System.out.println(file.getName());//前台传入的名字
    System.out.println(file.getOriginalFilename());//原始的名字
    System.out.println(file.getSize());
    //将上传的文件保存在服务器
    String dir="C:/Users/Hu Liupan/Desktop/test";
    FileOutputStream uts = null;
    try {
        InputStream ips=  file.getInputStream();//上传文件的输入流
        String filename = file.getOriginalFilename();//前台传入文件的原始的名字
        uts = new FileOutputStream(new File (dir,filename));
        IOUtils.copy(ips, uts);
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if(uts!=null) {
            try {
                uts.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return "redirect:upload.jsp";
}
}

8、文件下载

(1)在参数中添加response参数

(2)方法加上注解@ResponsBody

@RequestMapping("/down")
@ResponseBody//添加这样的注解,告诉SpringMVC所以的响应都由response处理
public void download(HttpServletResponse response){
    File file = new File("C:/Users/Hu Liupan/Desktop/test/盲打练习.txt");
    //定义输入流
    FileInputStream fis = null;
    try{
        //设置可选择下载还是打开的窗体,没有这个代码下载的文件就会在浏览器中打开。
        response.setHeader("Content-Disposition", "attachment;filename=盲打练习.txt");
        fis = new FileInputStream(file);
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(fis, outputStream);
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        if(fis!=null){
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

9、springMVC的拦截器

(1)拦截器类 org.springframework.web.servlet.HandlerInterceptor
preHandle:执行处理器前调用 ,返回true or false 如果为false,拦截请求
postHandle:处理器调用完成后,但是视图合并前
afterCompletion:视图合并后调用

public class DemoInteceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("DemoInteceptor.preHandle()");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("DemoInteceptor.postHandle()");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("DemoInteceptor.afterCompletion()");
    }
}

(2)配置拦截器

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/*"/>
        <bean class="com.it520.controller.DemoInteceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值