1、MVC 框架作用:
- 將 url 映射到 java 類或 java 類的方法
- 封裝用戶提交的數據
- 處理請求-調用相關的業務處理-封裝響應數據
- 將響應的數據進行渲染 jsp,html,freemaker 等
2、Spring MVC 是一個輕量級的基於響應的 MVC 框架
3、Spring MVC 優勢
- 性能比 Struts2 好
- 簡單,便捷,易學
- 和 Spring 無縫集成(使用 spring ioc, aop)
- 使用約定優先於配置
- 能夠進行簡單 junit 測試
- 支持 Restful 風格
- 異常處理
- 本地化,國際化
- 數據驗證,類型轉換
- 攔截器
- 使用的公司多
4、結構
spring-beans
spring-context
spring-core
spring-web
spring-webmvc
commons-logging
項目目錄
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── pengshiyu
│ │ └── controller
│ │ └── HelloController.java
│ ├── resources
│ │ └── springmvc-servlet.xml
│ └── webapp
│ ├── WEB-INF
│ │ ├── jsp
│ │ │ └── hello.jsp
│ │ └── web.xml
│ └── index.html
└── test
└── java
配置文件
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-mvc-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<!-- tomcat7插件 maven 命令 tomcat7:run 啓動項目-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
<!--添加忽略war包檢查標籤,則可以讓tomcat7:run指令正常啓動tomcat-->
<ignorePackaging>true</ignorePackaging>
<contextFile>src/main/webapp/WEB-INF/web.xml</contextFile>
<contextReloadable>true</contextReloadable>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
src/main/webapp/WEB-INF/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">
<!-- 配置分發器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 表示容器再啓動時立即加載servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 處理所有URL -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
src/main/resources/springmvc-servlet.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:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 渲染器-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<!-- 結果視圖的前綴-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 結果視圖的後綴-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置請求和處理器-->
<bean name="/hello" class="com.pengshiyu.controller.HelloController"/>
</beans>
控制器
src/main/java/com/pengshiyu/controller/HelloController.java
package com.pengshiyu.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
// 封裝要顯示的數據
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", "Tom");
modelAndView.addObject("age", 25);
// 視圖名
modelAndView.setViewName("hello");
return modelAndView;
}
}
視圖文件
src/main/webapp/WEB-INF/jsp/hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
${name}
${age}
訪問測試
GET http://localhost:8080/hello
Tom 25
Spring-MVC 註解開發
修改配置文件
src/main/resources/springmvc-servlet.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:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 渲染器-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<!-- 結果視圖的前綴-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 結果視圖的後綴-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置請求和處理器-->
<!-- <bean name="/hello" class="com.pengshiyu.controller.HelloController"/>-->
<!-- 掃描包下註解 -->
<context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
修改 Controller
package com.pengshiyu.controller;
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
public class HelloController {
@RequestMapping("/hello")
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
// 封裝要顯示的數據
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", "Tom");
modelAndView.addObject("age", 24);
// 視圖名
modelAndView.setViewName("hello");
return modelAndView;
}
}
配置總結
1、通過 url 對應 bean
適用於小型的應用系統
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 請求和處理器 -->
<bean name="/hello" class="com.pengshiyu.controller.HelloController"/>
2、爲 url 分配 bean
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- 請求名 - 處理器id-->
<prop key="/hello">helloController</prop>
</props>
</property>
</bean>
<bean id="helloController" class="com.pengshiyu.controller.HelloController"/>
3、註解
<!-- 掃描包下註解 -->
<context:component-scan base-package="com.pengshiyu.controller"/>
Controller 配置對應的註解
結果跳轉方式
1、返回 ModelAndView 對象
根據 view 的名稱和視圖解析器,會跳轉到指定的頁面
頁面:視圖解析器的前綴+ view name + 視圖解析器的後綴
springmvc-servlet.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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 渲染器-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<!-- 結果視圖的前綴-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 結果視圖的後綴-->
<property name="suffix" value=".jsp"/>
</bean>
<context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
package com.pengshiyu.controller;
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
public class HelloController {
@RequestMapping("/hello")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 封裝要顯示的數據
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", "Tom");
// 相當於:
// request.setAttribute("name", "Tom");
modelAndView.setViewName("hello");
// WEB-INF/jsp/hello.jsp
// 類似轉發
return modelAndView;
}
}
2、返回字符串
不需要視圖解析器
springmvc-servlet.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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@RequestMapping("/hello")
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.getWriter().println("hello");
}
}
3、重定向(地址改變)
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@RequestMapping("/hello")
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.sendRedirect("index.jsp");
}
}
或者
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 不需要視圖解析
return "redirect:index.jsp";
}
}
4、轉發(地址不變)
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@RequestMapping("/hello")
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
request.setAttribute("name", "Tom");
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
或者
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
return "hello";
}
}
或者
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
return "forward:index.jsp";
}
}
數據處理
1、提交數據
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String handleRequest(String name){
System.out.println(name);
return "index.jsp";
}
}
GET http://localhost:8080/hello
null
GET http://localhost:8080/hello?name=Tom
Tom
2、指定參數名
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String handleRequest(@RequestParam("uname") String name){
System.out.println(name);
return "index.jsp";
}
}
GET http://localhost:8080/hello?uname=Tom
Tom
3、提交對象
實體類
package com.pengshiyu.bean;
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.pengshiyu.controller;
import com.pengshiyu.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/user")
public String user(User user){
System.out.println(user);
return "index.jsp";
}
}
GET http://localhost:8080/user?name=Tom&age=23
User{name='Tom', age=23}
將數據顯示到 UI 層
1、通過 ModelAndView 需要視圖解析器
package com.pengshiyu.controller;
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
public class HelloController {
@RequestMapping("/hello")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 封裝要顯示的數據
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", "Tom");
// 相當於:
// request.setAttribute("name", "Tom");
modelAndView.setViewName("hello");
// WEB-INF/jsp/hello.jsp
// 類似轉發
return modelAndView;
}
}
2、通過 ModelMap 不需要視圖解析器
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/user")
public String user(String name, ModelMap modelMap){
System.out.println(name);
modelMap.addAttribute("name", name);
return "index.jsp";
}
}
區別:ModelAndView ModelMap
相同點:
- 都可以將數據封裝顯示到表示層頁面
不同點:
- ModelAndView 可以指定跳轉的視圖,而 ModelMap 不能
- ModelAndView 需要視圖解析器,而 ModelMap 不需要配置
亂碼和 Restful
通過過濾器解決
web.xml
<!-- 處理亂碼-->
<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>
2、Restful
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/user/{id}")
public String user(@PathVariable int id, ModelMap modelMap){
System.out.println(id);
modelMap.addAttribute("name", id);
return "/index.jsp";
}
}
GET http://localhost:8080/user/123
123
3、通過參數訪問處理方法
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/user")
public class HelloController {
// /user?method=add
@RequestMapping(params = {"method=add"}, method = RequestMethod.GET)
public String add(ModelMap modelMap){
modelMap.addAttribute("name", "add");
return "/index.jsp";
}
// /user?method=delete
@RequestMapping(params = {"method=delete"}, method = RequestMethod.GET)
public String delete(ModelMap modelMap){
modelMap.addAttribute("name", "delete");
return "/index.jsp";
}
}
文件上傳
依賴
commons-io
commons-fileupload
pom.xml
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
配置文件
src/main/resources/springmvc-servlet.xml
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
<property name="maxUploadSize" value="10485760000"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
src/main/java/com/pengshiyu/controller/HelloController.java
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@Controller
public class HelloController {
@RequestMapping(value = "/upload", method = RequestMethod.GET)
public String upload(){
return "/template/upload.jsp";
}
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
String path = request.getRealPath("/uploads");
InputStream is = file.getInputStream();
System.out.println(file.getOriginalFilename());
OutputStream os = new FileOutputStream(new File(path, file.getOriginalFilename()));
int len = 0;
byte[] buffer = new byte[400];
while ((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}
is.close();;
os.close();
return "/index.jsp";
}
}
src/main/webapp/template/upload.jsp
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" />
</form>
Ajax 和 JSON
1、Ajax
爲了直接獲取 html 文件,將配置文件匹配規則修改如下
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 處理所有URL -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class HelloController {
@RequestMapping(value = "/ajax")
public void ajax(String name, HttpServletResponse response) throws IOException {
System.out.println(name);
response.getWriter().println("ok");
}
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<input id="name" type="text" />
<script>
$(function () {
$("#name").blur(function () {
$.post(
"/ajax.do",
{
name: $("#name").val(),
},
function (res) {
alert(res);
}
);
});
});
</script>
2、JSON
jackson-annotations
jackson-core
jackson-databind
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</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.11.0</version>
</dependency>
配置 JSON 轉換器
<?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
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 將對象轉換爲JSON-->
<bean id="stringConverter"
class="org.springframework.http.converter.StringHttpMessageConverter"
>
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"
/>
<!-- 已廢棄 org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringConverter"/>
<ref bean="jsonConverter"/>
</list>
</property>
</bean>
<context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
package com.pengshiyu.controller;
import com.pengshiyu.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Controller
public class HelloController {
@RequestMapping("/json")
@ResponseBody
public List<User> ajax() throws IOException {
List<User> users = new ArrayList<User>();
users.add(new User("Tom", 23));
users.add(new User("Jack", 24));
return users;
}
}
攔截器
interceptor
1、實現 HandlerInterceptor 接口
DispatcherServlet
package com.pengshiyu.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
// 在請求處理的方法執行之前執行,
// 返回true執行下一個攔截器,
// 返回false不執行下一個攔截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
// 在處理方法執行之後執行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
// 在DispatcherServlet 之後執行 清理工作
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
2、配置攔截器
<?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
">
<context:component-scan base-package="com.pengshiyu.controller"/>
<!-- 配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 攔截所有請求-->
<mvc:mapping path="/**"/>
<bean class="com.pengshiyu.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
3、執行順序
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class HelloController {
@RequestMapping("/echo")
public void echo(HttpServletResponse response) throws IOException {
System.out.println("echo");
response.getWriter().println("echo");
}
}
preHandle
echo
postHandle
afterCompletion
登錄攔截器實現
配置
<!-- 配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 攔截所有請求-->
<mvc:mapping path="/**"/>
<bean class="com.pengshiyu.interceptor.MyInterceptor">
<property name="allowedUrls">
<list>
<value>login.do</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
攔截器
package com.pengshiyu.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public class MyInterceptor implements HandlerInterceptor {
private List<String> allowedUrls;
// 在請求處理的方法執行之前執行,
// 返回true執行下一個攔截器,
// 返回false不執行下一個攔截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
// 解決中文打印亂碼輸出
response.setContentType("text/html;charset=utf-8");
// 判斷session
Object user = request.getSession().getAttribute("user");
if(user != null){
return true;
}
// 判斷放行路徑
String url = request.getRequestURL().toString();
System.out.println(url);
for(String temp: allowedUrls){
if(url.endsWith(temp)){
return true;
}
}
// 如果沒有登錄就重定向到登錄頁面
response.sendRedirect("/login.do");
return false;
}
// 在處理方法執行之後執行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
// 在DispatcherServlet 之後執行 清理工作
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
public List<String> getAllowedUrls() {
return allowedUrls;
}
public void setAllowedUrls(List<String> allowedUrls) {
this.allowedUrls = allowedUrls;
}
}
User 類
package com.pengshiyu.bean;
public class User {
private String name;
private String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
Controller
package com.pengshiyu.controller;
import com.pengshiyu.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@Controller
public class UserController {
@RequestMapping("/userInfo")
public void userInfo(HttpSession session, HttpServletResponse response) throws IOException {
User user = (User) session.getAttribute("user");
response.getWriter().println(user);
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() throws IOException {
return "/template/login.jsp";
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public void login(User user, HttpSession session, HttpServletResponse response) throws IOException {
String message = "";
if ("root".equals(user.getName()) && "123".equals(user.getPassword())) {
message = "登錄成功";
session.setAttribute("user", user);
} else {
message = "用戶名或密碼錯誤";
}
response.getWriter().println(message);
}
}
登錄頁
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h2>登錄</h2>
<form action="/login.do" method="post">
<input type="text" name="name">
<input type="text" name="password">
<input type="submit" value="提交">
</form>