二: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了,因此这也是作为一名程序猿需要掌握的主流框架.框架选择多了.应对多变的需求和业务时,可实行的方案自然就多了. 只 ... 
随机推荐
- ArrayList 可以完全替代数组吗?
			本文已收录到 GitHub · AndroidFamily,有 Android 进阶知识体系,欢迎 Star.技术和职场问题,请关注公众号 [彭旭锐] 加入 Android 交流群. 前言 大家好, ... 
- Python3 Scrapy 框架学习
			1.安装scrapy 框架 windows 打开cmd输入 pip install Scrapy 2.新建一个项目: 比如这里我新建的项目名为first scrapy startproject fir ... 
- 【Java SE】Day02 数据类型转换、运算符、方法入门
			一.数据类型转换 1.自动转换 取值范围小在运算时会提升为取值范围大的类型 byte+int=int int+double=double 转换规则:byte.short.char-->int-- ... 
- Hadoop如何保证自己的江湖地位?Yarn功不可没
			前言 任何计算任务的运行都离不开计算资源,比如CPU.内存等,那么如何对于计算资源的管理调度就成为了一个重点.大数据领域中的Hadoop之所以一家独大,深受市场的欢迎,和他们设计了一个通用的资源管理调 ... 
- LoadRunner11录制脚本
			1.打开LoadRunner11后界面如下: 2.点击"创建/编辑脚本",会打开一个新窗口,如下: 3.这里新建一个web/html格式的测试.点击"文件"-& ... 
- 浅谈入行Qt桌面端开发程序员-从毕业到上岗(1):当我们说到桌面端开发时,我们在谈论什么?
			谈谈我自己 大家好,我是轩先生,是一个刚入行的Qt桌面端开发程序员.我的本科是双非一本的数学专业,22年毕业,只是部分课程与计算机之间有所交叉,其实在我毕业的时候并没有想过会成为一名程序员,也没有想过 ... 
- 用Python来写个小型购物车程序
			0x1 前言 Python语言能做很多东西的,像数据分析啊.自动化.开发. 爬虫(真的很棒哟,初学者玩很有成就感的啊哈哈)等等还有挺多. 0x2 用Python编写的一个小型购物车程序 import ... 
- django.db.migrations.exceptions.NodeNotFoundError: Migration apitest.0001_initial dependencies reference nonexistent parent node ('product', '0001_initial')
			执行python manage.py makemigrations时出现以下错误 D:\autotestplat>python manage.py makemigrations Tracebac ... 
- 发送http2请求
			有时服务器会检测http协议版本,有http/1.1和h2,requests发送的是http1.1的请求 # pip install httpx client = httpx.Client(http2 ... 
- [python] 向量检索库Faiss使用指北
			Faiss是一个由facebook开发以用于高效相似性搜索和密集向量聚类的库.它能够在任意大小的向量集中进行搜索.它还包含用于评估和参数调整的支持代码.Faiss是用C++编写的,带有Python的完 ... 
