【JavaEE】Spring Web-MVC

目录

Spring Web MVC 是什么

什么是Serlet

什么是MVC

什么是Spring MVC

使用Spring MVC

建立连接

@RequestMapping

请求

传递单个参数

传递多个参数

传递对象

后端参数重命名

 传递数组

传递集合

传递JSON数据

获取url参数-@pathvariable

上传文件@RequestPart

获取Cookie

Session

获取Header

响应

返回静态页面

返回HTML代码片段

返回JSON

设置状态码

设置Header

应用分层

如何分层

MVC与三层架构的区别和联系


 

Spring Web MVC 是什么

Sring Web MVC就是基于 Serlet API构建的Web框架. 它从一开始就包含在Spring框架中. 也可以简称Spring MVC

什么是Serlet

Serlet它是一种实现动态页面的技术.说准确一点Serlet就是一套Java Web开发的规范,或者是技术标准. 它是不能去做任何事情的,需要有人去实现这套开发规范. 实现这套开发规范就是真正的去编写代码实现里面提到的各种功能,包括类,方法,属性.这套规范sun公司是开放的,其他公司也可以实现这套规范.现在常用的Serlet产品有Tomcat,Weblogic,Jetty等,它们都可以叫做Serlet容器.Serlet容器就是用来管理程序猿编写的serlet类.我们Spring boot中就是内置了Tomcat.

什么是MVC

MVC它是软件工程中的一种软件架构设计的模式. 它把软件系统分为模型,视图,控制器三个部分.

视图: 在应用程序这中用来和浏览器进行交互,展现数据资源.

模型: 用来处理程序中数据逻辑的部分.

控制器: 它用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳转回哪个视图.就是用来连接视图和模型的.

这就类似于去海底捞吃火锅:

进去服务器来接待客户点餐,点完餐后将菜单交给前厅,前厅再根据菜单要求给后厨发出指令,后厨就负责准备菜. 准备好后,前厅再告诉服务器这是为x号桌准备的.

服务器就是视图,前厅就是控制器,后厨就是模型.

什么是Spring MVC

MVC是一种构架设计模式,也是一种思想,而Spring MVC就是对MVC思想的具体实现. 除此之外,Spring MVC还是一个Web框架,所以Spring MVC是一个实现了MVC思想的web框架. 而Spring boot将Spring MVC给集成进去了. 且Spring在实现MVC的时候,也做出了一些自己的改变. 请求会直接到达控制器,让控制器来处理.

这就和饭店吃饭,有的地方是前厅来负责接待客人,帮助客人点餐,也就是Controller来负责接收客户的请求.

使用Spring MVC

因为是web框架,我们在浏览器中输入url后,我们的Spring MVC项目就可以感应到用户的请求,且给予相应.

所以我们学习Spring MVC,也就是学习如何通过游览器和用户程序进行交互.分为三个方面:

建立连接: 将客户端和Java程序连接起来,访问一个地址可以调用到我们的Spring程序.

请求: 用户请求时,会携带一些参数,在程序中我们就要想办法获取到这些参数. 

响应: 执行逻辑后,就要把执行的结果返回给用户.

掌握了这三个功能,就掌握了Spring MVC.

建立连接

在Spring MVC中,我们使用@RequestMapping来实现yur路由映射,也就是浏览器连接程序的作用.

代码实现:

import org.springframework.web.bind.annotation.*;
@RequestMapping("/say")
@RestController
public class Requst {@RequestMapping("/sayHi")public String say1() {return "hello, SpringMVC";}

访问http://127.0.0.1:8080/say/sayHi就可以看到hello,SpringMVC了.

@RequestMapping

它是Spring MVC中常用的一种注解,它是用来注册接口的路由映射的. 当服务接收到请求时,路径为sayHi的请求就会调用sayHi这个方法的代码. 加上@RestConteoller,Spring才会去看这个类中方法有没有加@RequestMapping这个注解. 且@RequestMapping即可修饰类,也可以修饰方法. 访问的地址是类路径+方法路径. @RequestMapping各种请求类型都可以使用.

@RequestMapping标识类: 表示设置映射请求的请求路径的初始信息.

@RequestMapping标识方法: 表示设置映射请求路径的具体信息.

路由映射:当用户访问uer时,将用户的请求对应到应用程序中某个类的某个方法的过程就叫做路由映射.

请求

访问不同路径,就是发送不同的参数.在发送请求的同时,可能会带一些参数,我们需要知道如何传递参数到后端以及如何接受.

传递单个参数

@RequestMapping("/say")
@RestController
public class Requst {@RequestMapping("/r11/{name}")public String r1(String username) {return "name: " + username;}

注意:

url和参数名称不一致,是拿不到值的. 

使用基本类型来接收参数,参数必须传,不然会报500错误.类型不匹配会报400错误,对于参数为空的数据,建议使用包装类型.

传递多个参数

@RequestMapping("/say")
@RestController
public class Requst {@RequestMapping("/r3")public String say3(Integer age, String name, Integer id) {return "接收到: " + age + name + id;}
}

当有多个参数时,前后端进行匹配时按照参数的名称来进行匹配的,所以位置不影响后端获取参数的结果.

传递对象

package com.example.demo;import lombok.Data;@Data
public class Student {private String name;private Integer age;private int Id;}
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r4")public String say4(Student student) {return "接收到: " + student;}
}

Spring会根据参数名称来自动绑定到对象的各个属性中,如果某个参数没传递,则赋值为null,基本类型为默认值.

后端参数重命名

@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r6")public String say5(@RequestParam("name") String uername) {return uername;}
}

使用@RequestParam进行参数重命名时,请求参数只能和@RequestParam声明的名称一致,才能进行参数绑定和赋值.且使用@RequestParam后参数变成了必传参数.(它的required默认为true)

 传递数组

@RequestMapping("/say")
@RestController
public class Requst {@RequestMapping("/r8")public String say8(String[] array) {return Arrays.toString(array);}
}

传递集合

@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r9")public String r9(@RequestParam() List<String> list) {return "list:" +list;}
}

集合参数和数组类似,同一个请求参数名有多个,且需要使用@RequestParam来绑定参数关系(默认情况下,请求中参数名相同的多个值是封装到数组中的)

传递JSON数据

json的数据是在键值对key和value中,数据用,分割 对象用{}, 数组用[]表示 值可以为对象,也可以为数组,数组中可以有多个对象.

@RequestBody:表示请求正文, 意思是这个注解作用在请求正文的数据绑定,请求参数必须写在请求正文中.

 @RequestMapping("/r10")public String r10(@RequestBody Student student) {return "接收到: " + student;}

获取url参数-@pathvariable

@pathvariable: 路径变量

这个注解作用就是将请求url路径上的数据绑定,默认是传递参数写在url上,SpringMVC就可以获取到

@RequestMapping("/r11/{name}")public String  r11(@PathVariable("name") String username) {return "name: " + username;}

上传文件@RequestPart

@RequestMapping("/say")
@RestController
public class Requst {@RequestMapping("/r12")public String  r12(@RequestPart("filename") MultipartFile file) {String filename = file.getOriginalFilename();return "file: " + filename;}
}

获取Cookie

传统获取cookie:

@RequestMapping("/getc")public String getCookie(HttpServletRequest request) {String name = request.getParameter("name");Cookie[] cookkies = request.getCookies();StringBuilder builder = new StringBuilder();if (cookkies!=null){for (Cookie ck:cookkies) {builder.append(ck.getName()+":"+ck.getValue());}}return "Cookie: " + builder;}

HttpServletRequest,HttpServletResponse是Servlet提供的两个类,是SpringMVC的内置对象(因为Spring MVC是基于Servlet进一步封建的),需要使用时直接声明即可.

简易获取Cookie:

 @RequestMapping("/getc1")public String getCookie1(@CookieValue("bite") String bite) {return "Cookie: " + bite;}

Session

Session存储

@RequestMapping("/setc")public String setsess(HttpServletRequest request) {//getSession()是通过request中的Cookie中的SessionID来获取到对应的Session对象.HttpSession session = request.getSession();session.setAttribute("name", "zhangsan");session.setAttribute("n", "zhang");return "设置成功";}

获取Session的两种方式:

HttpSession getSession(boolean create);
HttpSession getSession();

getSession(boolean create): 参数如果为True,则不存在会话时会创建新的会话;参数如果为false,则当不存在会话时返回null.

getSession(): 和getSession(true)含义一样,默认值为true;

Object getAttribute(String name)

返回Session会话中具有指定名称的对象,如果没有,返回null.

简易获取Session

@RequestMapping("/getSess2")
public String sess2(@SessionAttribute(value = "username",required = false)
String username) {
return "username:"+username;
}
@RequestMapping("/getSess3")
public String sess3(HttpSession session) {
String username = (String)session.getAttribute("username");
return "username:"+username;
}

获取Header

传统获取Header:

@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
{
String userAgent = request.getHeader("User-Agent");
return name + ":"+userAgent;
}

简易获取Header:

@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
return "userAgent:"+userAgent;
}

RequestHeader的参数值为HTTP请求报头中的Key.

响应

Http相应结果可以是数据,也可以是静态页面,也可以针对响应设置状态码,Header信息等.

返回静态页面

我们需要将前端页面放在static包下.

后端代码访问:

@Controller
public class ResponseController {@RequestMapping("/index")public Object index() {return "/index.html";}

注意:

@RestController = Controller + ResponseBody

@Controller: 定义一个控制器, Spring框架启动时加载,把这个对象交给Spring管理

@ResponseBody: 定义返回的数据格式为非视图,返回一个text/html信息.它即可以在类上,也可以在方法上.

想要返回视图用@Controller即可.

返回HTML代码片段

后端返回数据时,如果数据中有HTML代码,也会被游览器解析:

@Controller
public class ResponseController {@ResponseBody@RequestMapping("/returnhtml")public String returnhtml() {return "<H1>我是index页面</H1>";}
}

返回JSON

Spring MVC也可以返回JSON,后端方法返回结果为对象:

@ResponseBody@RequestMapping("/returnjson")public HashMap<String, String> returnjson() {HashMap<String, String> hash = new HashMap<>();hash.put("java", "110");hash.put("mysql", "110");return hash;}

设置状态码

SpringMVC会根据我们的方法返回结果自动设置响应状态码,但也可以手动指定状态码.

@ResponseBody@RequestMapping("/setstatus")public Object setstatus(HttpServletResponse response) {response.setStatus(404);return "666";}

设置Header

Http相应报头会向客户端传递一些附加信息,比如服务程序的名称,请求的资源已移动到新地址等.这些信息通过@RequestMapping注解的属性来实现.

@RequestMapping源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective({ControllerMappingReflectiveProcessor.class})
public @interface RequestMapping {String name() default "";@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};
}

1. value: 指定映射的URL
2. method:指定请求的method类型, 如GET,POST等
3. consumes: 指定处理请求(request)的提交内容类型(Content-Type),例如application/json,
text/html;
4. produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回 
5. Params:指定request中必须包含某些参数值时,才让该⽅法处理
6. headers:指定request中必须包含某些指定的header值,才能让该⽅法处理请求 

设置Content-Type

@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {
return "{\"success\":true}";
}

设置其他Header

这需要使用HttpServletResPonse提供的方法来进行设置:

@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","MyHeaderValue");
return "设置Header成功";
}

应用分层

应用分层是一种设计思想,它是将应用程序分为N个层次,分别负责各自的职责,MVC设计模式就是分层的具体体现.

如何分层

这里我们将整体分为三个层次,将用户视图和业务隔离开来,通过控制器连接起来,可以很好的视线逻辑的解耦.现在流行的开发发方式是前后端分离的方式,后端开发工程师不需要关注前端的实现,我们Java后端又有了一种新的分层架构: 把整体架构分为表现层,业务逻辑层,数据层,这种分层方式称为"三层架构".

表现层(Controller): 展现数据结果和接受用户指令.

业务逻辑层(Service): 负责处理业务逻辑

数据层(Dao): 负责存储管理与应用相关的数据.

在编写代码时,我们就可以分为三个包来具体实现三层架构:

model是用来放实体类的.

MVC与三层架构的区别和联系

这两者可以说都是软件工程中的架构模式.

MVC中视图和控制器合起来对应的是三层架构中的表现层,模型对应的就是三层架构中的业务层,数据层,实体类.

这两者是从不同角度进行了抽象:

MVC强调的是数据和视图分离,将数据展示和数据处理分开,通过控制器对两者组合.而三层架构抢到的是不同维度数据处理的高内聚和低耦合,将业务处理,数据库,交互页面的逻辑分开.

但是它们两者的目的都是一样的,都是解耦,分层,代码复用.


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/600110.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++【组合模式】

简单介绍 组合模式是一种结构型设计模式&#xff0c; 只有在可以将对象拆分为【树状结构】的情况下使用。并且像使用独立对象一样使用它们。 常用于表示与图形打交道的用户界面组件或代码的层次结构。 基础理解 Q&#xff1a;为什么要用组合模式 &#xff1f; A&#xff1a;在…

SAP操作教程第14期:SAP B1如何进行自定义字段位置设置

服务对于企业而言永远是重中之重&#xff0c;想要提高服务呼叫效率&#xff0c;员工必须能够快速扫描单据和主数据中的重要信息&#xff0c;及时响应客户。那么&#xff0c;拥有适合企业业务流程的表单则是必不可少的前提。 所以&#xff0c;今天我们就来了解一下&#xff0c;在…

大模型应用解决方案:基于ChatGPT和GPT-4等Transformer架构的自然语言处理

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

Redis: 配置文件详解(Redis.conf)

文章目录 一、Units二、INCLUDES三、NETWORK四、GENERAL五、SECURITY六、LIMITS 一、Units 单位&#xff0c;配置大小单位&#xff0c;开头定义了一些基本的度量单位&#xff0c;只支持bytes&#xff0c;不支持bit&#xff0c;大小写不敏感 二、INCLUDES 包含&#xff0c;多…

如何明确的选择IT方向?

一、明确目标 作为初学者&#xff0c;先树立自己目标&#xff0c;找到自己感兴趣的IT行业&#xff0c;IT行业分很多种&#xff0c;听的最多次的无非不就是web前端工、程序员、后端、大数据、网络运维等。学习知识也是为了找到更好的工作&#xff0c;所以我建议先去boss直聘、五…

海外网红营销的UGC策略:激发用户创意,提升品牌知名度

在当今数字时代&#xff0c;品牌营销已经从传统的广告宣传转变为了与用户互动和参与密切相关的形式。UGC作为一种强大的营销策略&#xff0c;正在成为品牌提升知名度和美誉度的关键手段之一。尤其是通过海外网红的传播&#xff0c;UGC的影响力更是得到了进一步放大。本文Nox聚星…

自定义gitlog格式

git log命令非常强大而好用&#xff0c;在复杂系统的版本管理中扮演着重要的角色&#xff0c;但默认的git log命令显示出的东西实在太丑&#xff0c;不好好打扮一下根本没法见人&#xff0c;打扮好了用alias命令拍个照片&#xff0c;就正式出道了&#xff01; 在使用git查看lo…

适用于 Windows 10 的 10 大免费数据恢复软件

数据丢失可能是一场噩梦&#xff0c;尤其是在涉及重要文件和文档时。无论是由于意外删除、系统崩溃还是病毒攻击&#xff0c;找到适合 Windows 10 的文件夹恢复软件都可以在恢复丢失的数据方面发挥重要作用。在本指南中&#xff0c;我们将探索适用于 Windows 10 用户的 10 大免…

会话控制 与 IMS基本概念

目录 1. 因特网和电信网的介绍 2. 7号信令的分层结构及其作用 3. 基本的呼叫过程(ISUP流程) 4. 多媒体通信中的会话的概念 5. 关于IMS 5.1 IMS介绍 5.2 IMS控制层中的主要网元&#xff08;主要分为两类&#xff09; 5.3 现在来了解呼叫会话控制功能这一类的网元 6. 总…

Day108:代码审计-PHP模型开发篇MVC层动态调试未授权脆弱鉴权未引用错误逻辑

目录 案例1-Xhcms-动态调试-脆弱的鉴权逻辑 案例2-Cwcms-动态调试-未引用鉴权逻辑 案例3-Bosscms-动态调试-不严谨的鉴权逻辑 知识点&#xff1a; 1、PHP审计-动态调试-未授权安全 2、PHP审计-文件对比-未授权安全 3、PHP审计-未授权访问-三种形态 动态调试优点: 环境配置&…

BM44 有效括号序列(Stack)

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param s string字符串 * return bool布尔型*/public boolean isValid (String s) {// write code hereStack<Characte…

QA测试开发工程师面试题满分问答7: 线程、协程、进程的定义和使用场景

线程、协程和进程是计算机编程中用于实现并发执行的概念。它们具有不同的含义、区别和使用方式&#xff0c;下面是对它们的详细解释和具体例子&#xff1a; 线程&#xff08;Thread&#xff09; 线程是操作系统能够进行运算调度的最小单位。它是进程中的一个实体&#xff0c;…