什么是Spring MVC?
Spring MVC 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一。
Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架
- 导入jar包
<!-- spring相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springFramework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springFramework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springFramework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${springFramework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springFramework.version}</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
fastjson与jackson作用一样可以选用任何一个,主流是jackson
jackson可以运用注释将所需内容转换为json字符串类型
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.8</version>
</dependency>
- 配置文件web.xml(WEB-INF下)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<!-- 配置DispatchcerServlet前端控制器,请求集合点 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Spring mvc下的配置文件的位置和名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
注意: <param-value>classpath:springmvc.xml</param-value>用于配置spring mvc的配置文件的位置和名称,这里说明会新建一个springmvc.xml的配置文件。
这里的servlet-mapping表示拦截的模式,这里是“/”,表示对于非jsp请求进行拦截。
- Springmvc.xml(scr下)
在src目录下新建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-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.neusoft.controller"></context:component-scan>
<!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value="/WEB-INF/views/"></property>
<property name = "suffix" value = ".jsp"></property>
</bean>
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:resources location="/js/" mapping="/js/**"/>
</beans>
<context:component-scan base-package="com.neusoft.controller"></context:component-scan>
表示spring监听的范围,这里是在com.neusoft.controller下
静态资源访问<mvc:resources>
如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理,否则对css,js等文件的请求会被DispatcherServlet拦截。
spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。告诉springmvc框架,描述的静态资源,无须DispatcherServlet拦截,以及查询的目录。
SpringMVC应用
-
首先要在类的前面添加“Controller”注解,表示是spring的控制器,这里会写一个方法hello()
-
hello方法上方有一个@RequestMapping, 是用于匹配请求的路径,比如这里匹配的请求路径就是“http://localhost:8080/helloworld”,即当tomcat服务启动后,在浏览器输入这个url时,如果在这个方法打断点了,就会跳入该方法。
//第一种写路径的方法 在方法前通过注解@GetMapping("/user/add")将路径写全
@Controller
public class HelloController1 {
@GetMapping("/user/add")
public void hello(){
System.out.println("hello springmvc2");
}
@RequestMapping("/user/ald")
public void hello1(){
System.out.println("hello nigun");
}
}
//第二种写路径的方法 在类前通过@GetMapping("/user")将一级路径配好
@Controller
@GetMapping("/user")
public class HelloController1 {
@GetMapping("/add")
public void hello(){
System.out.println("hello springmvc2");
}
@RequestMapping("/ald")
public void hello1(){
System.out.println("hello nigun");
}
}
- 返回值类型
String -- 可以转发和重定向,Model可以代替request传值
ModelAndView
void
在请求转发通过return进行返回时可以不用将路径写全但是要在Springmvc.xml中有如下的配置(只有只有请求转发可以使用)
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value="/WEB-INF/views/"></property>
<property name = "suffix" value = ".jsp"></property>
</bean>
- 返回ModelAndView
返回ModelAndView时最常见的一种返回结果。需要在方法结束的时候定义一个ModelAndView对象,并对Model和View分别进行设置。
@Controller
public class HelloWorldController {
@RequestMapping("/abc")
public ModelAndView abc(){
// 相当于request.setAttribute
ModelAndView modelAndView = new ModelAndView();
//相当于请求转发
modelAndView.addObject("username","zhangsan");
modelAndView.setViewName("success");
return modelAndView;
}
}
- 返回String
1). 字符串代表逻辑视图名(默认做的是请求转发)
真实的访问路径=“前缀”+逻辑视图名+“后缀”
注意:如果返回的String代表逻辑视图名的话,那么Model的返回方式如下:
@RequestMapping("/helloworld")
public String hello(Model model){
model.addAttribute("username","zhangsan");
System.out.println("hello world");
return "success";
}
2):代表redirect重定向(不走视图解析器)
redirect的特点和servlet一样,使用redirect进行重定向那么地址栏中的URL会发生变化,同时不会携带上一次的request
案例:
@Controller
public class HelloWorldController {
@RequestMapping("/helloworld")
public String hello(Model model){
model.addAttribute("username","zhangsan");
System.out.println("hello world");
return "success";
}
@RequestMapping("/abc")
public ModelAndView abc(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username","zhangsan");
modelAndView.setViewName("success");
return modelAndView;
}
@RequestMapping("/redirect")
public String redirect(){
return "redirect:login.do";
}
}
3):代表forward转发
通过forward进行转发,地址栏中的URL不会发生改变,同时会将上一次的request携带到写一次请求中去
案例:
@Controller
public class HelloWorldController {
@RequestMapping("/helloworld")
public String hello(Model model){
model.addAttribute("username","zhangsan");
System.out.println("hello world");
return "success";
}
@RequestMapping("/abc")
public ModelAndView abc(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username","zhangsan");
modelAndView.setViewName("success");
return modelAndView;
}
@RequestMapping("/redirect")
public String redirect(){
return "forward:login";
}
}
- 返回void
返回这种结果的时候可以在Controller方法的形参中定义HTTPServletRequest和HTTPServletResponse对象进行请求的接收和响应
1)使用request转发页面
request.getRequestDispatcher("转发路径").forward(request,response);
2)使用response进行页面重定向
response.sendRedirect("重定向路径");
3)也可以使用response指定响应结果
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().println("json串");
@RequestMapping("/returnvoid.do")
public void returnvoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// request.getRequestDispatcher("转发路径").forward(request,response);
// response.sendRedirect("重定向路径");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().println("json串");
}
以上三种返回值没有什么重要和不重要的分别,一般来说都会使用到, 只不过有的时候使用的方式会有一些细微的差别
当页面通过ajax发过来请求后 ,将所需内容通过json字符串形式返回,fastjson与jackjson的对比
/*fastjson*/
@GetMapping("serch")
public void serch(@RequestParam("name") String name, HttpServletResponse response) throws IOException {
Student student = new Student();
if(name.equals("mike")){
student.setUsername("MIKE");
student.setPassword("123456");
student.setAge(99);
response.getWriter().println(JSON.toJSONString(student));
}else{
student.setUsername("haha");
student.setPassword("000000");
student.setAge(-1);
response.getWriter().println(JSON.toJSONString(student));
}
}
/*jackjson*/
@GetMapping("serch")
@ResponseBody // 利用jackson返回json字符串
public Student serch(@RequestParam("name") String name) throws IOException {
Student student = new Student();
if(name.equals("mike")){
student.setUsername("MIKE");
student.setPassword("123456");
student.setAge(99);
}else{
student.setUsername("haha");
student.setPassword("000000");
student.setAge(-1);
}
return student;
}
- @RequestMapping 后路径全写与简写对比
@RequestMapping("/atr")
public class HelloController {
@RequestMapping(value = "/add",method = RequestMethod.GET)
public void hello(){
System.out.println("hello springmvc");
}
@PostMapping("/ald")
public void hello1(){
System.out.println("hello gun");
}
}
- 响应ajax时可以通过@ResponseBody或类前加注解@RestController返回其它类型值
@ResponseBody
public int login(Userinfo userinfo, HttpSession session, HttpServletResponse response) throws IOException {
if(userinfo.getUsername().equals("mike")&&userinfo.getPassword().equals("123")){
return 1;
}else {
return 0;
}
}
@GetMapping("/serch1")
@ResponseBody
public Userinfo serch1(Integer id){
Userinfo userinfo=new Userinfo();
userinfo.setUsername("tom");
userinfo.setPassword("123");
userinfo.setSex(1);
return userinfo;
}
上传图片
在页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析
在springmvc.xml中配置multipart类型解析器。
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--限制文件大小-->
<property name="maxUploadSize" value="80000"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
上传图片代码
页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="upload.do" method="post" enctype="multipart/form-data">
<h2>文件上传</h2>
文件:<input type="file" name="file1"/><br/><br/>
用户名:<input type="text" name="username">
<br/><br/>
图片:<img src="${imgpath}"/><br/><br/>
<input type="submit" value="上传"/>
</form>
</body>
</html>
controller方法
@Controller
public class uploadController {
@RequestMapping("/upload.do")
public void doUpload(@RequestParam MultipartFile file1, HttpServletRequest request) throws IOException {
String strName = request.getParameter("username");
System.out.println(strName);
if(file1.isEmpty()){
System.out.println("文件未上传!");
}
else {
//得到上传的文件名
String fileName = file1.getOriginalFilename();
//得到服务器项目发布运行所在地址
String strFolder = request.getServletContext().getRealPath("/image")+ File.separator;
File folder = new File(strFolder);
if(!folder.exists())
{
folder.mkdir();
}
// 此处未使用UUID来生成唯一标识,用日期做为标识
String strNewFilePath = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+ fileName;
String strFinalPath = strFolder + strNewFilePath;
//查看文件上传路径,方便查找
System.out.println(strFinalPath);
//把文件上传至path的路径
File localFile = new File(strFinalPath);
file1.transferTo(localFile);
request.getSession().setAttribute("imgpath", "image"+ File.separator+strNewFilePath);
}
}
}
拦截器
拦截器是用来动态拦截 action 调用的对象。它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个 action 执行前阻止其执行,同时也提供了一种可以提取 action 中可重用部分的方式
拦截器工作原理HandlerInterceptor概述
-
在SpringMVC 中定义一个Interceptor是比较非常简单,实现HandlerInterceptor接口。
-
HandlerInterceptor接口主要定义了三个方法:
1. boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle)方法:该方法将在请求处理之前进行调用,只有该方法返回true,才会继续执行后续的Interceptor和Controller,当返回值为true 时就会继续调用下一个Interceptor的preHandle 方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法;
2. void postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法:该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用,可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。
3. void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法:该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理。
简单的一个例子:
xml需要配置:两种配置方式(对所有的请求记性拦截,对特定的请求进行拦截)
<!-- 拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/page/add" />
<bean class="com.neuedu.interceptor.CheckInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
interceptors类
package com.neuedu.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class CheckInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if(request.getSession().getAttribute("login_user") == null) {
request.getRequestDispatcher("/WEB-INF/jsp/user/login.jsp").forward(request, response);
return false;
}else {
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println(456);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println(789);
}
}
URL 模板模式映射
@RequestMapping(value="/ viewItems/{id}")
{×××}占位符,请求的URL可以是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。
@RequestMapping("/viewItems/{id}")
public @ResponseBody viewItems(@PathVariable("id") String id) throws Exception{
}
如果RequestMapping中表示为"/viewItems/{id}",id和形参名称一致,@PathVariable不用指定名称。
@RequestMapping("/viewItems/{id}")
public @ResponseBody viewItems(@PathVariable String id) throws Exception{
}
多个参数
@Controller
@RequestMapping("/person")
public class PersonAction{
@RequestMapping(value="/delete/{id}/{name}")
public String delete(@PathVariable Integer id,@PathVariable String name){
System.out.println(id + " " + name) ;
return "person";
}
}
网友评论