二:Spring Mvc 框架
二:SpringMVC
异常码:
405:请求不允许
404:资源不存在
400:参数有问题
500:代码有问题
SpringMvc是Spring FrameWork提供的WEB组件,是目前的主流的实现MVC设计模式的框架,提供前端的路由映射、视图解析等
java web 开发者必要的框架
Spring mvc 功能
部分概念
MVC :
MVC 设计模式一般指 MVC 框架,M(Model)指数据模型层,V(View)指视图层,C(Controller)指控制层。使用 MVC 的目的是将 M 和 V 的实现代码分离,使同一个程序可以有不同的表现形式。其中,View 的定义比较清晰,就是用户界面。
视图层(View):负责格式化数据并把它们呈现给用户,包括数据展示、用户交互、数据验证、界面设计等功能。
控制层(Controller):负责接收并转发请求,对请求进行处理后,指定视图并将响应结果发送给客户端。
数据模型层(Model):模型对象拥有最多的处理任务,是应用程序的主体部分,它负责数据逻辑(业务规则)的处理和实现数据操作(即在数据库中存取数据)。
JSP+JavaBean
Servlet+JSP+JavaBean
优点
多视图共享一个模型,大大提高了代码的可重用性
MVC 三个模块相互独立,松耦合架构
控制器提高了应用程序的灵活性和可配置性
有利于软件工程化管理
缺点
原理复杂
增加了系统结构和实现的复杂性
视图对模型数据的低效率访问
SpringMvc的组件:
1)DispatcherServlet
DispatcherServlet 是前端控制器,从图 1 可以看出,Spring MVC 的所有请求都要经过 DispatcherServlet 来统一分发。DispatcherServlet 相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。
2)HandlerMapping
HandlerMapping 是处理器映射器,其作用是根据请求的 URL 路径,通过注解或者 XML 配置,寻找匹配的处理器(Handler)信息。
3)HandlerAdapter
HandlerAdapter 是处理器适配器,其作用是根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)。
4)Handler
Handler 是处理器,和 Java Servlet 扮演的角色一致。其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至 ModelAndView 对象中。
5)View Resolver
View Resolver 是视图解析器,其作用是进行解析操作,通过 ModelAndView 对象中的 View 信息将逻辑视图名解析成真正的视图 View(如通过一个 JSP 路径返回一个真正的 JSP 页面)。
6)View
View 是视图,其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等)。
7)HandlerExecutionChain:处理器执行链(包括两部分Handler和HandlerInterceptor)
SpringMVC 的执行流程如下
- 用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器);
- 由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)。
- DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
- HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
- Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
- HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
- DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
- ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
- DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
- 视图负责将结果显示到浏览器(客户端)。
SpringMvc 的具体使用
1.导入依赖:
<!-- springMvc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
</dependencies>
2.在web.xml中配值SpringMvc 的DispatchServlet
<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.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置扫包-->
<context:component-scan base-package="com.southwind.controller"></context:component-scan>
<!-- 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 前缀-->
<property name="prefix" value="/"></property>
<!-- 后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
4.创建Handller
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.xml.ws.RequestWrapper;
@Controller
public class HellowHandler {
@RequestMapping ("/index")
public String index(){
System.out.println("接受到了请求");
//返回逻辑视图
return "index";
}
}
流程梳理:
1.DispatcherServlet接收到url请求index,结合@RequestMapping("/index")注解将该请求交给index业务处理
2.执行index业务方法,控制台打印日志,并返回”index“字符串
3.组合springmvc.xml中的视图解析器配置,找到对应的资源;/index.jsp, 即根目录下的index.jsp文件,将该文件的jsp资源返回客户端。
搭建成功;
SpringMvc的常用注解
@RequestMapping()
SpringMvc通过@RequestMapping注解将URL请求与业务的方法进行映射,在控制器的类定义处定义方法处都可以添加@RequestMapping,在类定义处添加相当于多了一层访问路径。
value :指定URL请求的地址,是@RequestMapping的默认值。
method:请求的method类型包括 GET POST PUT DELETE
params 请求的参数
@Controller
public class HellowHandler {
@RequestMapping (value = "/index",params = {"id=1","name=tom"})
public String index(){
System.out.println("接受到了请求");
//返回逻辑视图
return "index";
}
}
参数绑定
params是对URL请求参数进行限制,不满足的URL不能访问,需要在业务方法中获取URL的参数值。
1.在业务方法定义时声明参数列表
2.给参数列表添加@RequsetParam 注解进行绑定
@Controller
public class HellowHandler {
@RequestMapping (value = "/index",params = {"id"})
public String index(@RequestParam("id") double id){
System.out.println("接受到了请求"+"id="+id);
//返回逻辑视图
return "index";
}
}
Springmvc也支持RESTful风格的URL传参
@RequestMapping (value = "/index/{id}")
public String index1(@PathVariable("id") double id){
System.out.println("接受到了请求"+"id="+id);
//返回逻辑视图
return "index";
}
映射Cookie
@RequestMapping (value = "/Cookie")
public String index2(@CookieValue("JSESSIONID") String session){
System.out.println("接受到了请求"+"session="+session);
//返回逻辑视图
return "index";
}
使用POJO绑定参数
Springmvc会自动更据请求参数与POJO的属性名匹配,自动为该对象填充属性值,并支持属性级联。
乱码
<!-- 过滤器-->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
User:
package com.southwind.entity;
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private Address address;
}
Address;
package com.southwind.entity;
import lombok.Data;
@Data
public class Address {
private Integer code;
private String name;
}
jsp:
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-06
Time: 17:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/add">
<table>
<tr>
<td>编号:</td>
<td>
<input type="text" name="id">
</td>
</tr>
<tr>
<td>姓名:</td>
<td>
<input type="text" name="name">
</td>
</tr>
<tr>
<td>地址编号:</td>
<td>
<input type="text" name="address.code">
</td>
</tr>
<tr>
<td>地址信息:</td>
<td>
<input type="text" name="address.name">
</td>
</tr>
<tr>
<td>
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
</body>
</html>
controller:
@RequestMapping("/add")
public String add(User user){
System.out.println(user);
return "addUser";
}
JSP页面的转发和重定向
转发是服务器行为,重定向是客户端行为。转发耗时比重定向少。
转发——>客户浏览器发送HTTP请求——>web服务器接受请求——>调用内部一个方法在容器内部完成请求处理和转发动作——>再将转发跳转到的那个网页资源返回给客户; 转发只能在同一个容器内完成 转发的时候浏览器地址是不会变的,在客户浏览器里只会显示第一次进入的那个网址或者路径,客户看不到这个过程,只是得到了想要的目标资源。转发行为浏览器只做了一次请求。(转发只能跳转一次)
重定向——>客户浏览器发送HTTP请求——>web服务器接受请求后发送302状态码以及新的位置给客户浏览器——>客户浏览器发现是302响应,则自动再发送一个新的HTTP请求,请求指向新的地址(302:Found 临时移动,但资源只是临时被移动。即你访问网址A,但是网址A因为服务器端的拦截器或者其他后端代码处理的原因,会被重定向到网址B。)——>服务器根据此请求寻找资源发个客户;再客户浏览器中显示的是重定向之后的路径,客户可以看到地址的变化。重定向行为浏览器做了至少两次请求。(重定向可以跳转多次
SpringMVC默认是以转发,(地址栏没有改变0
重定向:redirect
@RequestMapping("/add")
public String add(User user){
System.out.println(user);
return "redirect:/addUser.jsp";
}
转发;forward
SpringMVC的数据绑定:
在后端直接得到前端的HTTP中的数据。
HTTP请求中的传输的参数都是String类型,Handler业务方法中的参数是开发者指定的数据类型,int Integer,,因此要进行数据类型的绑定
由HabderAdapter完成参数的绑定:
基本数据类型:
@RequestMapping("/baseType")
@ResponseBody
public String baseType(int id){
return "id="+id;
}
请求必须由id参数,否则500错误,同时id的值 , 必须为数值不然为400异常。
包装类
@RequestMapping("/baseType1")
@ResponseBody
public String baseType(Integer id){
return "id="+id;
}
请求必须由id参数,否则500错误,同时id的值 , 必须为数值不然为400异常。不传为null。
利用@RequestParam处理参数(设置默认值)
@RequestMapping("/baseType1")
@ResponseBody
public String baseType(@RequestParam(value = "id",required = true,defaultValue = "0") Integer id){
return "id="+id;
}数组
@RequestMapping("/arrayType")
@ResponseBody
public String arrayType(String[] names){
StringBuffer stringBuffer =new StringBuffer();
for(String str:names){
stringBuffer.append(str).append(" ");
}
return "names: "+stringBuffer.toString();
}POJO
package com.southwind.entity;
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private Address address;
}@RequestMapping("/add")
public String add(User user){
System.out.println(user);
return "redirect:/addUser.jsp";
}
乱码;
<mvc:annotation-driven>
<!-- 消息转换器-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
List
SpringMVC不支持直接转换Lis类型,需要包装成Object
List的自定义包装类
控制类:
@RequestMapping("/listType")
@ResponseBody
public String listType(UserList users){
StringBuffer stringBuffer =new StringBuffer();
for(User user:users.getList()){
stringBuffer.append(user);
}
return "用户"+stringBuffer.toString();
}
实体类:
package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class UserList {
private List<User> list;
}
jsp
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-06
Time: 17:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/listType">
<input type="text" name="list[0].id">
<input type="text" name=" list[0].name">
<input type="text" name="list[1].id">
<input type="text" name=" list[1].name">
<input type="submit" value=" 提交">
</form>
</body>
</html>
注意;User要有无参构造
JSON
1.对于返回是text:
<script type="text/javascript">
$(function () {
var user= {
"id":1,
"name":"张三"
}
$.ajax({
url:"/jsonType",
data:JSON.stringify(user),
type:"POST",
contentType:"application/json;charset=UTF-8",
dataType:"text",
success:function (data) {
// console.log(data);
var obj=eval("("+data+")")
alert(obj.id)
alert(obj.name)
}
})
})
</script>
2.直接是json
页面:
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-06
Time: 17:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function () {
var user= {
"id":1,
"name":"张三"
}
$.ajax({
url:"/jsonType",
data:JSON.stringify(user),
type:"POST",
contentType:"application/json;charset=UTF-8",
dataType:"JSON",
success:function (data) {
// console.log(data);
// var obj=eval("("+data+")")
alert(data.id)
alert(data.name)
}
})
})
</script>
</head>
<body>
</body>
</html>
controller:业务方法:
@RequestMapping("/jsonType")
@ResponseBody
public User jsonType(@RequestBody User user){
System.out.println(user);
user.setId(2);
return user;
}
配置:
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--json依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
</dependencies>
<mvc:annotation-driven>
<!-- 消息转换器-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"></property>
</bean>
<!-- fastjson-->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
注意;
- JSON数据必需用JSON。stringify()妆化成字符串
- contentType:"application/json;charset=UTF-8"不能省略
Spring mvc 的视图层解析
调用web资源给域对象传值
page
request
session
application
业务数据的绑定是指将业务的数据绑定给jsp对象,业务数据的绑定是由ViewResolver来完成,开发时,我们先添加业务数据,在交给ViewResolve来绑定数据,因此学习的重点在于如何的添加数据,Springmvc提供了一下几中的方式来添加业务:
- Map
- Model
- ModelAndView
- @SessionAttribute
- @ModelAttribute
- Servlet API
业务绑定到request对象
Map
springmvc 在调用业务方法之前会创建一个隐含的对象作为业务的数据的容器,设置业务方法的入参为Maq类型,springmvc会将隐含的对象的引用传递格入参(默认是给Request)
@RequestMapping("/map")
public String map(Map<String,Object> map) {
User user =new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
return "show";
}
Model
@RequestMapping("/model")
public String model(Model model) {
User user =new User();
user.setId(1);
user.setName("张三");
model.addAttribute("user",user);
return "show";
}
Mo'delAndView
Mo'delAndView不但包含业务数据也包括了视图信息,如果用Mo'delAndView来处理业务数据,业务数据的返回值必需是Mo'delAndView对象
操作;
1.填充业务数据
2.绑定业务信息
@RequestMapping("/modelAndView1")
public ModelAndView modelAndView1() {
ModelAndView modelAndView =new ModelAndView();
User user =new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
modelAndView.setViewName("show");
return modelAndView;
}完整路径
@RequestMapping("/modelAndView2")
public ModelAndView modelAndView2() {
ModelAndView modelAndView =new ModelAndView();
User user =new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
View view =new InternalResourceView("/show.jsp");
modelAndView.setView(view);
return modelAndView;
}直接给视图
@RequestMapping("/modelAndView3")
public ModelAndView modelAndView3() {
ModelAndView modelAndView =new ModelAndView("show");
User user =new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
return modelAndView;
}传递view对象
@RequestMapping("/modelAndView4")
public ModelAndView modelAndView4() {
View view =new InternalResourceView("/show.jsp");
ModelAndView modelAndView =new ModelAndView(view);
User user =new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
return modelAndView;
}
使用Map集合
@RequestMapping("/modelAndView5")
public ModelAndView modelAndView5() {
Map<String,Object> map =new HashMap<>();
User user =new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
ModelAndView modelAndView =new ModelAndView("show",map);
return modelAndView;
}
直接map和view
@RequestMapping("/modelAndView6")
public ModelAndView modelAndView6() {
Map<String,Object> map =new HashMap<>();
User user =new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
View view =new InternalResourceView("/show.jsp");
ModelAndView modelAndView =new ModelAndView(view,map);
return modelAndView;
}
…
HttpServletRequest
Spring mvc 在业务方法中直接得到Servlet的原生web资源,只需要在方法的定义时添加HttpServletRequest入参即可,在方法体中直接使用request
<!--导入servlet的api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
@RequestMapping("/request")
public String request(HttpServletRequest request) {
User user =new User();
user.setId(1);
user.setName("张三");
request.setAttribute("user",user);
return "show";
}
@ModelAttribute
定义一个方法来要填充到业务数据中的对线
给方法添加@ModelAttribute,只是添加对象,不做业务
@ModelAttribute
public User getUser(){
User user =new User();
user.setId(1);
user.setName("张三");
return user;
}
@RequestMapping("/modelAttribute")
public String ModelAttribute() {
return "show";
}
@ModelAttribute,当Handler无论接受到哪格方法都会先调用@ModelAttribute修饰的方法,并将返回值作为业务数据,此时业务方法只需要返回试图即可。
假如返回数据,还是会被@ModelAttribute的数据据覆盖。
而如果没有返回值,要手动填充Map或Model
直接给Model的优先级更高
key-value
key值默认是:对应类的小写首字母
业务数据绑定到Session
HttpSession
@RequestMapping("/session")
public String session(HttpSession httpSession){
User user =new User();
user.setId(1);
user.setName("张三");
httpSession.setAttribute("user",user);
return "show";
}
}@SessionAttributes注解
默认都是在request下添加,但是注解了@SessionAttributes都会自动的添加到Session中
@SessionAttributes(value = "user")
@SessionAttributes(type = User.Class)
多个:
@SessionAttributes(value = {"user","students"})
Spring Mvc自定义的数据类型转换器:
一:Date
1.创建DateConverter 类,并实现Converter接口:需要指定泛型
package com.southwind.converter;
import lombok.SneakyThrows;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter<String, Date> {
private String pattern;
public DateConverter(String pattern){
this.pattern=pattern;
}
@Override
public Date convert(String s) {
SimpleDateFormat simpleDateFormat =new SimpleDateFormat(this.pattern);
try {
return simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
2.配置springMvC
<mvc:annotation-driven conversion-service="conversionService">
<!-- 消息转换器-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"></property>
</bean>
<!-- fastjson-->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 消息转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.southwind.converter.DateConverter">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
</bean>
</list>
</property>
</bean>
3.控制器:
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.xml.crypto.Data;
import java.util.Date;
@Controller
public class ControverHandler {
@RequestMapping("/date")
@ResponseBody
public String date(Date date){
return date.toString();
}
}
二:实体类;
转换器:
package com.southwind.converter;
import com.southwind.entity.Student;
import org.springframework.core.convert.converter.Converter;
public class StudentConverter implements Converter<String, Student> {
@Override
public Student convert(String s) {
String[] args=s.split("-");
Student student =new Student();
student.setId(Integer.parseInt(args[0]));
student.setName(args[1]);
student.setAge(Integer.parseInt(args[2]));
return student;
}
}
配置:
<!-- 消息转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.southwind.converter.DateConverter">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
</bean>
<bean class="com.southwind.converter.StudentConverter">
</bean>
</list>
</property>
</bean>
控制器:
@RequestMapping("/student")
@ResponseBody
public String student(Student student, HttpServletResponse response){
response.setCharacterEncoding("utf-8");
return student.toString();
}
Spring mvc 的RESTful集成
RESTful是当前比较流行的互联网架构模型,通过统一的规范来完成不同端的数据访问和交互,RESTful(资源表现层状态转化)
优点:结构清晰,有统一的标准,扩展性好
Resources
资源是指网路中的某个具体文件,可以是文件、图片、视频、音频等,是网路中真实存在的一个实体。
获取它:可以通过统一资源定位负找到这个实体,URL,每个资源都有一个特定的URL,通过URL就可以找到一个具体的资源
Pepersentation
资源表现层,资源的具体表现层次,例如一段文字、可以用TXT、HTML、XML、JSON、等不同的形式来描述它。
State Transfer
状态转化是指客户端和服务器之间的数据交互,因为HTTP请求不能传输数据的状态,所有的状态都保存在服务器端,如果客户端希望访问到服务器的数据,就需要使其发生状态改变,同时这种状态的改变是建立在表现层上的。
RESTful的特点:
1.URL传递参数更加简洁
2.完成不同总端之间的资源共享,RESTful提供了一套规范,不同的终端之间只需要遵守规范,就可以实现数据的交互
RESTful四中表现类型,
HTTP中的:
GET 获取资源
POST创建资源
PUT修改资源
DELETE删除资源
基于RESTful的方式,增删改查分别操作使用不同的HTTP请求来访问。
传统的from表单只支持GET和POST
解决方法:
添加HiddenHttpMeethodFilter过滤器将POST转化为PUT或DELETE
HiddenHttpMeethodFilter实现原理:
HiddenHttpMeethodFilter检测请求的参数是否包含_method参数,如果包含则取出它的值,并且判断它的请求类型之后完成请求的类型的转换,然后继续传递。
实现步骤
1.在from表单中加入隐藏域的标签,name为_method,value为DELETE/PUT
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 14:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/update" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="提交">
</form>
<form action="/delete" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="DELETE提交">
</form>
</body>
</html>
web.xml配置
<filter>
<filter-name>HiddenHttpMthodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMthodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.控制器
@PutMapping("/update")
@ResponseBody
public String update(){
return "PUT已接受到请求";
}
@DeleteMapping("/delete")
public String delete(){
return "DELETE已接受请求";
}
需求分析
- 添加课程,成功返回全部课程信息
- 查询课程,通过id查找课程
- 修改课程,成功返回全部的课程信息
- 删除课程,成功返回删除之后的全部课程信息
代码实现
- JSP
- 添加课程
- 修改课程
- 课程展示
2.Course实体类
package com.southwind.entity;
import lombok.Data;
@Data
public class Course {
private Integer id;
private String name;
private Double prive;
}
3.CourseRepository
package com.southwind.respository;
import com.southwind.entity.Course;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class CourseRepository {
private Map<Integer, Course> courseMap;
public CourseRepository(){
courseMap=new HashMap<>();
courseMap.put(1,new Course(1,"java基础",Double.parseDouble("500")));
courseMap.put(2, new Course(2, "java高级", Double.parseDouble("500")));
courseMap.put(3, new Course(3, "企业级框架", Double.parseDouble("500")));
}
public Collection<Course> findAll(){
return courseMap.values();
}
public Course findById(Integer id){
return courseMap.get(id);
}
public void saveOrupdate(Course course){
courseMap.put(course.getId(),course);
}
public void delete (Integer id){
courseMap.remove(id);
}
}
4.CourseController:
package com.southwind.controller;
import com.southwind.entity.Course;
import com.southwind.respository.CourseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseRepository courseRepository;
@PostMapping("/save")
public String save(Course course){
courseRepository.saveOrupdate(course);
return "redirect:/course/findAll";
}
@GetMapping("/findAll")
public ModelAndView findAll(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("list",courseRepository.findAll());
return modelAndView;
}
@DeleteMapping("/delete/{id}")
public String deleteById(@PathVariable("id")Integer id){
courseRepository.delete(id);
return "redirect:/course/findAll";
}
@GetMapping("/findById/{id}")
public ModelAndView findById(@PathVariable("id") Integer id){
ModelAndView modelAndView =new ModelAndView();
modelAndView.setViewName("edit");
modelAndView.addObject("course",courseRepository.findById(id));
return modelAndView;
}
@PutMapping("/update")
public String update(Course course){
courseRepository.saveOrupdate(course);
return "redirect:/course/findAll";
}
}
4.jsp
首页(查询和删除修改)
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 10:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<table>
<tr>
<td>编号</td>
<td>名称</td>
<td>价格</td>
<td>删除</td>
</tr>
<c:forEach items="不能识别此Latex公式:
{list}" var="course">
<tr>
<td>{course.id}</td>
<td>不能识别此Latex公式:
{course.name}</td>
<td>{course.price}</td>
<td>
<form action="/course/delete/不能识别此Latex公式:
{course.id}" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="删除" >
</form>
<a href="/course/findById/{course.id}">修改</a>
</td></tr>
</c:forEach></table>
</body>
</html><%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 15:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/course/update" method="post">
<input type="hidden" name="_method" value="PUT">
<table>
<tr>
<td>编号:</td>
<td><input type="text" name="id" readonly value="不能识别此Latex公式:
{course.id}"></td>
</tr>
<tr>
<td>名称:</td>
<td><input type="text" name="name" value="{course.name}"></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="text" name="price" value="${course.price}"></td>
</tr>
<tr>
<td><input type="submit" value="修改"></td>
</tr>
</table>
</form>
</body>
</html>jsp<br /><%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 15:10
To change this template use File | Settings | File Templates.
--%><br /><%@ page contentType="text/html;charset=UTF-8" language="java" %><br /><br />
Title
<br /><br /> </p>
<form action="/course/save" method="post">
<table>
<tr>
<td>课程编号</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td>课程名称</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>课程价格</td>
<td><input type="text" name="price"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
<p><br /><br />
SpringMvc的文件上传下载:
文件上传
单文件上传
1.底层使用的是Apache fileupload组件进行上传的功能,Springmvc 只是对其进行了封装,简化开发,
pom.xml
<!-- apache fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2.JSP页面处理
inpu的type设置为file
form表单的method设置为post
form表单的enctype设置为multipar/form-data
一:单文件:
JSP
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 16:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="img"/>
<input type="submit" value="提交"/>
</form>
<img src="${src}">
</body>
</html>
Handler
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
@Controller
@RequestMapping("/file")
public class fileHandler {
@PostMapping("/upload")
public String upload(@RequestParam("img")MultipartFile img, HttpServletRequest request) {
if(img.getSize()>0){
String path =request.getSession().getServletContext().getRealPath("file");
String fileName =img.getOriginalFilename();
File file =new File(path,fileName);
try {
img.transferTo(file);
request.setAttribute("src","/file/"+fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
return "upload";
}
}
配置解析器:
<!-- 配置转换器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
二:多文件:
@PostMapping("/uploads")
public String uploads(@RequestParam("imgs")MultipartFile[] imgs, HttpServletRequest request) {
List<String> pathlist = new ArrayList<>();
for (MultipartFile img : imgs) {
if (img.getSize() > 0) {
String path = request.getSession().getServletContext().getRealPath("file");
String fileName = img.getOriginalFilename();
File file = new File(path, fileName);
try {
img.transferTo(file);
pathlist.add("/file/" + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
request.setAttribute("list",pathlist);
return "upload";
}
<form action="/file/uploads" method="post" enctype="multipart/form-data">
file1:<input type="file" name="imgs"><br>
file1:<input type="file" name="imgs"><br>
<input type="submit" value="提交">
</form>
<c:forEach items="${list}" var="path">
<img src="${path}" width="300px">
</c:forEach>
文件下载
@GetMapping("/downLoad")
public void downLoad(String fileName, HttpServletRequest request, HttpServletResponse response){
if(fileName!=null){
String path = request.getSession().getServletContext().getRealPath("file");
File file =new File(path,fileName);
OutputStream outputStream=null;
if(file.exists()){
//设置下载文件
response.setContentType("application/force-downlocad");
//设置文件名
response.setHeader("Content-Dispoition","attachment;filename"+fileName);
try {
outputStream=response.getOutputStream();
outputStream.write(FileUtils.readFileToByteArray(file));
} catch (IOException e) {
e.printStackTrace();
}finally {
if(outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
Spring Mvc 数据校验的组件
有两种:
基于Vaildator接口进行校验
使用Annotation JSR-303标准校验
使用Vaildator接口会复杂点,开发者要自己定义规则,而Annotation JSR-303则是要开发者添加对应的校验注解即可。
基于Validator的接口*1.创建实体类:
package com.southwind.entity;
import lombok.Data;
@Data
public class Student {
// private Integer id;
// private String name;
// private Integer age;
private String name;
private String password;
}2.自定义数据校验器StudentValidator实现Validator接口,重写接口的抽象方法,加入校验规则。
package com.southwind.validation;
import com.southwind.entity.Student;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
public class StudentValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return Student.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors) {
ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空");
ValidationUtils.rejectIfEmpty(errors,"password",null,"密码不能为空");
}
}
3.业务方法:
package com.southwind.controller;
import com.southwind.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/validatior")
public class ValidatiorHandler {
//先数据绑定
@GetMapping("/login")
public String login(Model model){
model.addAttribute(new Student());
return "login";
}
@RequestMapping("/login")
public String login(@Validated Student student, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "login";
}else {
return "login";
}
}
}
package com.southwind.validation;
import com.southwind.entity.Student;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
public class StudentValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return Student.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors) {
ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空");
ValidationUtils.rejectIfEmpty(errors,"password",null,"密码不能为空");
}
}
Annotation JSR-303
Hibernater Validator,通过注解完成校验
名称 | 说明 |
---|---|
@Null | 被标注的元素必须为 null |
@NotNull | 被标注的元素必须不为 null |
@AssertTrue | 被标注的元素必须为 true |
@AssertFalse | 被标注的元素必须为 false |
@Min(value) | 被标注的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 被标注的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMax(value) | 被标注的元素必须是一个数字,其值必须大于等于指定的最大值 |
@DecimalMin(value) | 被标注的元素必须是一个数字,其值必须小于等于指定的最小值 |
@size | 被标注的元素的大小必须在指定的范围内 |
@Digits(integer,fraction) | 被标注的元素必须是一个数字,其值必须在可接受的范围内;integer 指定整数精度,fraction 指定小数精度 |
@Past | 被标注的元素必须是一个过去的日期 |
@Future | 被标注的元素必须是一个将来的日期 |
@Pattern(value) | 被标注的元素必须符合指定的正则表达式 |
配置:
pom.xml
<!-- JSP303-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.6.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.4.1.Final</version>
</dependency>
<mvc:annotation-driven></mvc:annotation-driven>
业务页面:
@GetMapping("/register")
public String register(Model model){
model.addAttribute(new Account());
return "register";
}
@PostMapping("/register")
public String register(@Valid Account account,BindingResult bindingResult ){
if(bindingResult.hasErrors()){
return "register";
}else {
return "success";
}
}
实体类:
package com.southwind.entity;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@Data
public class Account {
@NotEmpty(message = "用户名不能为空")
private String userName;
@Size(min = 6,max = 20,message = "长度为5到20位")
private String password;
@Email(regexp = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?",message = "请输入正确的表达式")
private String email;
@Pattern(regexp = "\\d{3}-\\d{8}|\\d{4}-\\{7,8}",message = "请输入正确的表达式")
private String phone;
}
页面:
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 19:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1> 用户登录</h1>
<form:form modelAttribute="account" action="/validatior/register">
用户名:<form:input path="userName"></form:input><form:errors path="userName"></form:errors><br>
密码:<form:input path="password"></form:input><form:errors path="password"></form:errors><br>
邮箱:<form:input path="email"></form:input><form:errors path="email"></form:errors><br>
电话:<form:input path="phone"></form:input><form:errors path="phone"></form:errors><br>
<input type="submit" value="提交">
</form:form>
</body>
</html>
spring mvc 的表单标签库
1.Student实体类
package com.southwind.POJO;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private Integer age;
private String gender;
}
2.Handler
package com.southwind.controller;
import com.southwind.POJO.Student;
import com.sun.org.apache.xpath.internal.operations.Mod;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/student")
public class StudenController {
@GetMapping("/get")
public String get(Model model){
Student student =new Student();
student.setId(1);
student.setAge(18);
student.setName("张三");
student.setGender("男");
model.addAttribute("student",student);
return "student";
}
}
3.JSP
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-07
Time: 20:53
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>学生编号</h1>
<form action="" method="post">
学生编号:<input type="text" value="${student.id}" readonly><br>
学生姓名:<input type="text" value="${student.name}"><br>
学生年龄;<input type="text" value="${student.age}"><br>
学生性别:<input type="text" value="${student.gender}"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
表单标签库的使用
1.JSP页面表单标签库的导入
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
2.将form表单的业务数据进行绑定,通过modelAttribute属性完成绑定,将modelAttribute的值设置位控制器象model对象存值是的name即可。
<%--@elvariable id="student" type="com.southwind.POJO.Student"--%>
<form:form modelAttribute="student" action="/student/update" method="post">
学生编号:<form:input path="id"></form:input><br>
学生姓名:<form:input path="name"></form:input><br>
学生年龄;<form:input path="age"></form:input><br>
学生性别:<form:input path="gender"></form:input><br>
<input type="submit" value="提交">
</form:form>
常用标签的使用
1.from:
<form:form modelAttribute="student" action="/student/update" method="post">
</form:form>
渲染的是HTML的from标签,通过modelAttribute属性绑定业务数据。
2.input:
<form:input path="name"></form:input><br>
渲染的是HTML的input标签,type="text" 绑定的是业务数据中的属性值,与path的业务属性值一样。支持级联
3.password:
<form:password path="age"></form:password><br>
渲染的是HTML的password标签,type="text" 绑定的是业务数据中的属性值,与path的业务属性值一样。但是不会在页面现实
4.checkbox:
<form:checkbox path="hobby" value="读书">
</form:checkbox>
渲染的是HTML的checkbox标签,type="text" 绑定的是业务数据中的属性值,与path的业务属性值一样。
有Boolean,数组,集合
boolean 为true选中 false为不选中。
student.setFlag(true)
check:<form:checkbox path="flag" value="读书">
</form:checkbox>数组,集合如果和集合中的元素和checkbox相同就选中
5.checkboxs:
<form:checkboxes path="name" items="${student.hobby}"></form:checkboxes>
渲染的是一组checkbox标签
item绑定别遍历的数组,path表述选中的数组
student.setHobby(Array.asList("读书","鞋子"))
path可以直接写属性名,item则要通过EL表达式从作用域对象中取值,不能直接写属性名。
6.radiobuttion
<form:radiobutton path="name" value="0"></form:radiobutton>
渲染的是一个HTML中的一个单选按钮,值相同为选中状态,值不同为不状态。
7.radiobuttion
<form:radiobuttons path="name" items="${student.name}"></form:radiobuttons>
渲染的是html中的一组单选按钮标签
item绑定别遍历的数组,path表述选中的数组
8.select
<form:select path="name" items="${student.name}"></form:select>
渲染的是html中的一组选择标签
item绑定别遍历的数组,path表述选中的数组
9.from:select结合form:optations使用
from:select只定义path form:optations写 items
10.from:select结合form:optation使用
from:select只定义path form:optation写 value
path与哪个valu相等,则默认选择
Springmvc 国际化
在不同的语言设置的浏览器自动显示不同的语言。
1.spring.mvc
<!-- 国计化资源文件-->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 多语言配置文件放在根路径 以langua开头-->
<property name="basename" value="classpath:language"></property>
<property name="useCodeAsDefaultMessage" value="true"></property>
</bean>
<!-- 拦截器-->
<mvc:interceptors>
<bean id="localeChangeInterceotor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="Lang"></property>
</bean>
</mvc:interceptors>
<!-- 配置SessionResolver,动态获取local对象存入Session-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
2.创建国际化资源文件:
language_en_US.properties
language.cn=\u4E2D\u6587
language.en=English
info=login
userbane=username
password=password
repassword=repassword
tel=tel
email=email
submit=submit
reset=reset
language_en_US.properties
language.cn=\u4E2D\u6587
language.en=English
info=\u767B\u5F55
userbane=\u7528\u6237\u540D
password=\u5BC6\u7801
repassword=\u786E\u8BA4\u5BC6\u7801
tel=\u7535\u8BDD
email=\u7535\u5B50\u90AE\u7BB1
submit=\u63D0\u4EA4
reset=\u91CD\u7F6E
业务页面:
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/inter")
public class InterHandler {
@GetMapping("/index")
public String index(){
return "inter";
}
}
二:Spring Mvc 框架的更多相关文章
- 手写Spring MVC框架(二) 实现访问拦截功能
前言 在上一篇文章中,我们手写了一个简单的mvc框架,今天我们要实现的功能点是:在Spring MVC框架基础上实现访问拦截功能. 先梳理一下需要实现的功能点: 搭建好Spring MVC基本框架: ...
- Spring MVC篇一、搭建Spring MVC框架
本项目旨在搭建一个简单的Spring MVC框架,了解Spring MVC的基础配置等内容. 一.项目结构 本项目使用idea intellij创建,配合maven管理.整体的目录结构如图: 其中ja ...
- Spring MVC 框架的架包分析,功能作用,优点
由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或是软件架构师,在学习和了解一个框架的时候,首先都应该知道的是这个框架的原理和与其有关j ...
- Spring mvc框架 controller间跳转 ,重定向 ,传参
一.需求背景 1. 需求:spring MVC框架controller间跳转,需重定向.有几种情况:不带参数跳转,带参数拼接url形式跳转,带参数不拼接参数跳转,页面也能显示. @Req ...
- spring mvc 框架搭建及详解
现 在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不 ...
- Spring MVC框架搭建
Spring MVC篇一.搭建Spring MVC框架 本项目旨在搭建一个简单的Spring MVC框架,了解Spring MVC的基础配置等内容. 一.项目结构 本项目使用idea intellij ...
- spring MVC框架入门(外加SSM整合)
spring MVC框架 一.什么是sping MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 W ...
- 戏说 Spring MVC 框架
Spring MVC 是 Spring 框架的一部分,和 Struts 一样都是属于 web 层框架,根据项目分层的思想,一个项目基本可以分为持久层,业务层和 web 层.而 Spring MVC 主 ...
- Spring MVC 框架学习
一.spirng的简介 Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情. ...
- Spring MVC 框架搭建及具体解释
如今主流的Web MVC框架除了Struts这个主力 外.其次就是Spring MVC了,因此这也是作为一名程序猿需要掌握的主流框架.框架选择多了.应对多变的需求和业务时,可实行的方案自然就多了. 只 ...
随机推荐
- windows环境变量修改器
软件及源码 前言 我一直再用win7的系统,当更改path环境变量的时候很难受, 就只能看到一段,然后前面有啥后面有啥都看不到,而且来回调整优先级的时候需要剪切粘贴,主要就是来回调节优先级特别麻烦.所 ...
- 【每日一题】2021年12月14日-82. 删除排序链表中的重复元素 II
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字. 返回同样按升序排列的结果链表. 来源:力扣(LeetCo ...
- go-carbon 1.5.2版本发布, 修复已知 bug 和新增功能及葡萄牙语翻译文件
carbon 是一个轻量级.语义化.对开发者友好的golang时间处理库,支持链式调用. 目前已被 [awesome-go](https://github.com/avelino/awesome-go ...
- 使用echarts(可视化图表库)
一:echarts 1.简介 一个基于 JavaScript 的开源可视化图表库 echarts官网使用教程: https://echarts.apache.org/zh/index.html 2.e ...
- Django三大主流Web框架(django版本安装-项目创建-应用创建-django三板斧)
目录 一:python三大主流web框架 1.python三大主流Web框架 2:三大主流web框架特点 二:正常运行Django项目所需要知道的注意事项 1.计算机的名称不能有中文,不然bug在哪你 ...
- k3s安装kubernetes环境
官方文档:https://docs.rancher.cn/k3s/ 官方文档:https://rancher.com/docs/k3s/latest/en/installation/install-o ...
- 万字长文详解 YOLOv1-v5 系列模型
一,YOLOv1 Abstract 1. Introduction 2. Unified Detectron 2.1. Network Design 2.2 Training 2.4. Inferen ...
- [seaborn] seaborn学习笔记1-箱形图Boxplot
文章目录 1 箱形图Boxplot 1. 基础箱形图绘制 Basic boxplot and input format 2. 自定义外观 Custom boxplot appearance 3. 箱型 ...
- 20 张图带你全面了解 HTTPS 协议,再也不怕面试问到了!
本文详细介绍了 HTTPS 相较于 HTTP 更安全的原因,包括对称加密.非对称加密.完整性摘要.数字证书以及 SSL/TLS 握手等内容,图文并茂.理论与实战结合.建议收藏! 1. 不安全的 HTT ...
- vulnhub靶场之BUFFEMR: 1.0.1
准备: 攻击机:虚拟机kali.本机win10. 靶机:BUFFEMR: 1.0.1,下载地址:https://download.vulnhub.com/buffemr/BuffEMR-v1.0.1. ...