Java学习路线-64:SpringMVC
发布日期:2021-07-01 06:11:41 浏览次数:2 分类:技术文章

本文共 24340 字,大约阅读时间需要 81 分钟。

1、MVC 框架作用:

  1. 将 url 映射到 java 类或 java 类的方法
  2. 封装用户提交的数据
  3. 处理请求-调用相关的业务处理-封装响应数据
  4. 将响应的数据进行渲染 jsp,html,freemaker 等

2、Spring MVC 是一个轻量级的基于响应的 MVC 框架

3、Spring MVC 优势

  1. 性能比 Struts2 好
  2. 简单,便捷,易学
  3. 和 Spring 无缝集成(使用 spring ioc, aop)
  4. 使用约定优先于配置
  5. 能够进行简单 junit 测试
  6. 支持 Restful 风格
  7. 异常处理
  8. 本地化,国际化
  9. 数据验证,类型转换
  10. 拦截器
  11. 使用的公司多

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

4.0.0
org.example
spring-mvc-demo
1.0-SNAPSHOT
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
8080
/
UTF-8
true
src/main/webapp/WEB-INF/web.xml
true
org.springframework
spring-core
5.2.6.RELEASE
org.springframework
spring-beans
5.2.6.RELEASE
org.springframework
spring-context
5.2.6.RELEASE
org.springframework
spring-web
5.2.6.RELEASE
org.springframework
spring-webmvc
5.2.6.RELEASE
org.springframework
spring-aop
5.2.6.RELEASE
org.springframework
spring-expression
5.2.6.RELEASE
commons-logging
commons-logging
1.2
javax.servlet
javax.servlet-api
4.0.1
provided
jstl
jstl
1.2

src/main/webapp/WEB-INF/web.xml

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
springmvc
/

src/main/resources/springmvc-servlet.xml

控制器

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/helloTom 25

Spring-MVC 注解开发

修改配置文件

src/main/resources/springmvc-servlet.xml

修改 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;@Controllerpublic 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

适用于小型的应用系统

2、为 url 分配 bean

helloController

3、注解

Controller 配置对应的注解

结果跳转方式

1、返回 ModelAndView 对象

根据 view 的名称和视图解析器,会跳转到指定的页面

页面:视图解析器的前缀+ view name + 视图解析器的后缀

springmvc-servlet.xml

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;@Controllerpublic 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

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;@Controllerpublic 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;@Controllerpublic 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;@Controllerpublic 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;@Controllerpublic 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;@Controllerpublic 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;@Controllerpublic 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;@Controllerpublic class HelloController {
@RequestMapping("/hello") public String handleRequest(String name){
System.out.println(name); return "index.jsp"; }}
GET http://localhost:8080/hellonullGET http://localhost:8080/hello?name=TomTom

2、指定参数名

package com.pengshiyu.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;@Controllerpublic class HelloController {
@RequestMapping("/hello") public String handleRequest(@RequestParam("uname") String name){
System.out.println(name); return "index.jsp"; }}
GET http://localhost:8080/hello?uname=TomTom

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;@Controllerpublic class HelloController {
@RequestMapping("/user") public String user(User user){
System.out.println(user); return "index.jsp"; }}
GET http://localhost:8080/user?name=Tom&age=23User{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;@Controllerpublic 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;@Controllerpublic class HelloController {
@RequestMapping("/user") public String user(String name, ModelMap modelMap){
System.out.println(name); modelMap.addAttribute("name", name); return "index.jsp"; }}

区别:ModelAndView ModelMap

相同点:

  1. 都可以将数据封装显示到表示层页面

不同点:

  1. ModelAndView 可以指定跳转的视图,而 ModelMap 不能
  2. ModelAndView 需要视图解析器,而 ModelMap 不需要配置

乱码和 Restful

通过过滤器解决

web.xml

CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*

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;@Controllerpublic 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/123123

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

commons-io
commons-io
2.7
commons-fileupload
commons-fileupload
1.4

配置文件

src/main/resources/springmvc-servlet.xml

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.*;@Controllerpublic 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

Ajax 和 JSON

1、Ajax

为了直接获取 html 文件,将配置文件匹配规则修改如下

springmvc
*.do
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;@Controllerpublic class HelloController {
@RequestMapping(value = "/ajax") public void ajax(String name, HttpServletResponse response) throws IOException {
System.out.println(name); response.getWriter().println("ok"); }}

2、JSON

jackson-annotations
jackson-core
jackson-databind

com.fasterxml.jackson.core
jackson-annotations
2.11.0
com.fasterxml.jackson.core
jackson-databind
2.11.0
com.fasterxml.jackson.core
jackson-core
2.11.0

配置 JSON 转换器

text/plain;charset=UTF-8
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;@Controllerpublic class HelloController {
@RequestMapping("/json") @ResponseBody public List
ajax() throws IOException {
List
users = new ArrayList
(); 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、配置拦截器

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;@Controllerpublic class HelloController {
@RequestMapping("/echo") public void echo(HttpServletResponse response) throws IOException {
System.out.println("echo"); response.getWriter().println("echo"); }}
preHandleechopostHandleafterCompletion

登录拦截器实现

配置

login.do

拦截器

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
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
getAllowedUrls() {
return allowedUrls; } public void setAllowedUrls(List
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;@Controllerpublic 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"%>

登录

转载地址:https://pengshiyu.blog.csdn.net/article/details/106909854 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java学习路线-65:整合 SSM-Spring+SpringMVC+MyBatis
下一篇:Java学习路线-63:maven整合ssm-spring+struts+mybatis

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月16日 19时14分10秒