Java学习路线-64:SpringMVC

简介: Java学习路线-64:SpringMVC

1、MVC 框架作用:

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

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

3、Spring MVC 优势

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

4、结构

8.jpg

spring-beans

spring-context

spring-core

spring-web

spring-webmvc

commons-logging

项目目录

.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── pengshiyu
    │   │           └── controller
    │   │               └── HelloController.java
    │   ├── resources
    │   │   └── springmvc-servlet.xml
    │   └── webapp
    │       ├── WEB-INF
    │       │   ├── jsp
    │       │   │   └── hello.jsp
    │       │   └── web.xml
    │       └── index.html
    └── test
        └── java

配置文件

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>spring-mvc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <!-- tomcat7插件 maven 命令 tomcat7:run 启动项目-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                    <uriEncoding>UTF-8</uriEncoding>
                    <!--添加忽略war包检查标签,则可以让tomcat7:run指令正常启动tomcat-->
                    <ignorePackaging>true</ignorePackaging>
                    <contextFile>src/main/webapp/WEB-INF/web.xml</contextFile>
                    <contextReloadable>true</contextReloadable>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
</project>

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

<?xml version="1.0" encoding="utf-8" ?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 配置分发器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!-- 表示容器再启动时立即加载servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 处理所有URL -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

src/main/resources/springmvc-servlet.xml

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
    <!-- 渲染器-->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <!-- 结果视图的前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 结果视图的后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 配置请求和处理器-->
    <bean name="/hello" class="com.pengshiyu.controller.HelloController"/>
</beans>

控制器

src/main/java/com/pengshiyu/controller/HelloController.java

package com.pengshiyu.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        // 封装要显示的数据
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name", "Tom");
        modelAndView.addObject("age", 25);
        // 视图名
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}

视图文件

src/main/webapp/WEB-INF/jsp/hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${name}
${age}

访问测试

GEGET http://localhost:8080/hello
Tom 25

Spring-MVC 注解开发

修改配置文件

src/main/resources/springmvc-servlet.xml

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
    <!-- 渲染器-->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <!-- 结果视图的前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 结果视图的后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 配置请求和处理器-->
<!--    <bean name="/hello" class="com.pengshiyu.controller.HelloController"/>-->
    <!-- 扫描包下注解 -->
    <context:component-scan base-package="com.pengshiyu.controller"/>
</beans>

修改 Controller

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController  {
    @RequestMapping("/hello")
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        // 封装要显示的数据
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name", "Tom");
        modelAndView.addObject("age", 24);
        // 视图名
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}

配置总结

1、通过 url 对应 bean

适用于小型的应用系统

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 请求和处理器 -->
<bean name="/hello" class="com.pengshiyu.controller.HelloController"/>

2、为 url 分配 bean

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <!-- 请求名 - 处理器id-->
            <prop key="/hello">helloController</prop>
        </props>
    </property>
</bean>
<bean id="helloController" class="com.pengshiyu.controller.HelloController"/>

3、注解

<!-- 扫描包下注解 -->
<context:component-scan base-package="com.pengshiyu.controller"/>

Controller 配置对应的注解


结果跳转方式

1、返回 ModelAndView 对象


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


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


springmvc-servlet.xml

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
    <!-- 渲染器-->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <!-- 结果视图的前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 结果视图的后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // 封装要显示的数据
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name", "Tom");
        // 相当于:
        // request.setAttribute("name", "Tom");
        modelAndView.setViewName("hello");
        // WEB-INF/jsp/hello.jsp
        // 类似转发
        return modelAndView;
    }
}

2、返回字符串

不需要视图解析器

springmvc-servlet.xml

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
    <context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        response.getWriter().println("hello");
    }
}

3、重定向(地址改变)

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        response.sendRedirect("index.jsp");
    }
}

或者

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // 不需要视图解析
        return "redirect:index.jsp";
    }
}

4、转发(地址不变)

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        request.setAttribute("name", "Tom");
        request.getRequestDispatcher("index.jsp").forward(request, response);
    }
}

或者

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        return "hello";
    }
}

或者

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        return "forward:index.jsp";
    }
}

数据处理

1、提交数据

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

2、指定参数名

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

3、提交对象

实体类

package com.pengshiyu.bean;
public class User {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.pengshiyu.controller;
import com.pengshiyu.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
    @RequestMapping("/user")
    public String user(User user){
        System.out.println(user);
        return "index.jsp";
    }
}
GET http://localhost:8080/user?name=Tom&age=23
User{name='Tom', age=23}

将数据显示到 UI 层

1、通过 ModelAndView 需要视图解析器

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // 封装要显示的数据
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name", "Tom");
        // 相当于:
        // request.setAttribute("name", "Tom");
        modelAndView.setViewName("hello");
        // WEB-INF/jsp/hello.jsp
        // 类似转发
        return modelAndView;
    }
}

2、通过 ModelMap 不需要视图解析器

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
    @RequestMapping("/user")
    public String user(String name, ModelMap modelMap){
        System.out.println(name);
        modelMap.addAttribute("name", name);
        return "index.jsp";
    }
}

区别:ModelAndView ModelMap


相同点:

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

不同点:

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

乱码和 Restful

通过过滤器解决

web.xml

<!-- 处理乱码-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2、Restful

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
    @RequestMapping("/user/{id}")
    public String user(@PathVariable int id, ModelMap modelMap){
        System.out.println(id);
        modelMap.addAttribute("name", id);
        return "/index.jsp";
    }
}
GET http://localhost:8080/user/123
123

3、通过参数访问处理方法

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/user")
public class HelloController {
     // /user?method=add
    @RequestMapping(params = {"method=add"}, method = RequestMethod.GET)
    public String add(ModelMap modelMap){
        modelMap.addAttribute("name", "add");
        return "/index.jsp";
    }
    // /user?method=delete
    @RequestMapping(params = {"method=delete"}, method = RequestMethod.GET)
    public String delete(ModelMap modelMap){
        modelMap.addAttribute("name", "delete");
        return "/index.jsp";
    }
}

文件上传

依赖

commons-io

commons-fileupload

pom.xml

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

配置文件

src/main/resources/springmvc-servlet.xml

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
        <property name="maxUploadSize" value="10485760000"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>

src/main/java/com/pengshiyu/controller/HelloController.java

ppackage com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@Controller
public class HelloController {
    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    public String upload(){
        return "/template/upload.jsp";
    }
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String upload(@RequestParam("file")  CommonsMultipartFile file, HttpServletRequest request) throws IOException {
        String path = request.getRealPath("/uploads");
        InputStream is = file.getInputStream();
        System.out.println(file.getOriginalFilename());
        OutputStream os = new FileOutputStream(new File(path, file.getOriginalFilename()));
        int len = 0;
        byte[] buffer = new byte[400];
        while ((len = is.read(buffer)) != -1){
            os.write(buffer, 0, len);
        }
        is.close();;
        os.close();
        return "/index.jsp";
    }
}

src/main/webapp/template/upload.jsp

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
  <input type="submit" />
</form>

Ajax 和 JSON

1、Ajax

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

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class HelloController {
    @RequestMapping(value = "/ajax")
    public void ajax(String name, HttpServletResponse response) throws IOException {
        System.out.println(name);
        response.getWriter().println("ok");
    }
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<input id="name" type="text" />
<script>
  $(function () {
    $("#name").blur(function () {
      $.post(
        "/ajax.do",
        {
          name: $("#name").val(),
        },
        function (res) {
          alert(res);
        }
      );
    });
  });
</script>

2、JSON

jackson-annotations

jackson-core

jackson-databind

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.0</version>
</dependency>

配置 JSON 转换器

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
    <!-- 将对象转换为JSON-->
    <bean id="stringConverter"
          class="org.springframework.http.converter.StringHttpMessageConverter"
    >
        <property name="supportedMediaTypes">
            <list>
                <value>text/plain;charset=UTF-8</value>
            </list>
        </property>
    </bean>
    <bean id="jsonConverter"
          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"
    />
    <!--  已废弃  org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="stringConverter"/>
                <ref bean="jsonConverter"/>
            </list>
        </property>
    </bean>
    <context:component-scan base-package="com.pengshiyu.controller"/>
</beans>
package com.pengshiyu.controller;
import com.pengshiyu.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Controller
public class HelloController {
    @RequestMapping("/json")
    @ResponseBody
    public List<User> ajax() throws IOException {
        List<User> users = new ArrayList<User>();
        users.add(new User("Tom", 23));
        users.add(new User("Jack", 24));
        return users;
    }
}

拦截器

interceptor

1、实现 HandlerInterceptor 接口

DispatcherServlet

package com.pengshiyu.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
    // 在请求处理的方法执行之前行,
    // 返回true执行下一个拦截器,
    // 返回false不执行下一个拦截器
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }
    // 在处理方法执行之后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }
    // 在DispatcherServlet 之后执行 清理工作
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

2、配置拦截器

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
    <context:component-scan base-package="com.pengshiyu.controller"/>
    <!-- 配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 拦截所有请求-->
            <mvc:mapping path="/**"/>
            <bean class="com.pengshiyu.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

3、执行顺序

package com.pengshiyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class HelloController {
    @RequestMapping("/echo")
    public void echo(HttpServletResponse response) throws IOException {
        System.out.println("echo");
        response.getWriter().println("echo");
    }
}
preHandle
echo
postHandle
afterCompletion

登录拦截器实现

配置

<!-- 配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 拦截所有请求-->
        <mvc:mapping path="/**"/>
        <bean class="com.pengshiyu.interceptor.MyInterceptor">
            <property name="allowedUrls">
                <list>
                    <value>login.do</value>
                </list>
            </property>
        </bean>
    </mvc:interceptor>
</mvc:interceptors>

拦截器

package com.pengshiyu.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public class MyInterceptor implements HandlerInterceptor {
    private List<String> allowedUrls;
    // 在请求处理的方法执行之前执行,
    // 返回true执行下一个拦截器,
    // 返回false不执行下一个拦截器
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        // 解决中文打印乱码输出
        response.setContentType("text/html;charset=utf-8");
        // 判断session
        Object user = request.getSession().getAttribute("user");
        if(user != null){
            return true;
        }
        // 判断放行路径
        String url = request.getRequestURL().toString();
        System.out.println(url);
        for(String temp: allowedUrls){
            if(url.endsWith(temp)){
                return true;
            }
        }
        // 如果没有登录就重定向到登录页面
        response.sendRedirect("/login.do");
        return false;
    }
    // 在处理方法执行之后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }
    // 在DispatcherServlet 之后执行 清理工作
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
    public List<String> getAllowedUrls() {
        return allowedUrls;
    }
    public void setAllowedUrls(List<String> allowedUrls) {
        this.allowedUrls = allowedUrls;
    }
}

User 类

package com.pengshiyu.bean;
public class User {
    private String name;
    private String password;
    public User() {
    }
    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

Controller

package com.pengshiyu.controller;
import com.pengshiyu.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@Controller
public class UserController {
    @RequestMapping("/userInfo")
    public void userInfo(HttpSession session, HttpServletResponse response) throws IOException {
        User user = (User) session.getAttribute("user");
        response.getWriter().println(user);
    }
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login() throws IOException {
        return "/template/login.jsp";
    }
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public void login(User user, HttpSession session, HttpServletResponse response) throws IOException {
        String message = "";
        if ("root".equals(user.getName()) && "123".equals(user.getPassword())) {
            message = "登录成功";
            session.setAttribute("user", user);
        } else {
            message = "用户名或密码错误";
        }
        response.getWriter().println(message);
    }
}

登录页

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h2>登录</h2>
<form action="/login.do" method="post">
    <input type="text" name="name">
    <input type="text" name="password">
    <input type="submit" value="提交">
</form>
相关文章
|
6月前
|
XML 前端开发 Java
java面试题之个人对SpringMvc的原理实现理解
java面试题之个人对SpringMvc的原理实现理解
|
3月前
|
JSON 前端开发 Java
【Java笔记+踩坑】SpringMVC基础
springmvc简介、入门案例、bean加载控制、PostMan工具的使用、普通和JSON和日期格式请求参数传递、响应JSON或jsp或文本、Rest风格
【Java笔记+踩坑】SpringMVC基础
|
XML 小程序 Java
Java-Servlet技术入门笔记-1
一、Servlet技术 1、什么是Servlet Servlet是JaveEE规范之一,规范就是接口 Servlet是JavaWeb三大组件之一。三大组件分别是:Servlet程序、Filter过滤器、Listener监听器 Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送来的请求,并响应数据给客户端 l
|
应用服务中间件 Windows
Java-Servlet技术入门笔记-3
五、HttpServletResponse类 1、作用 HttpServletResponse类和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息。我们如果需要设置返回给客户端的信息,都可以通过它来设置。
|
XML 存储 前端开发
Java-Servlet技术入门笔记-2
三、ServletContext类 1、什么是ServletContext 代表整个web工程,可以与程序的容器(Tomcat服务器)通信
|
设计模式 前端开发 安全
java之路—— SpringMVC的基本详解
java之路—— SpringMVC的基本详解
114 0
java202303java学习笔记第四十五天javaweb-springboot入门2
java202303java学习笔记第四十五天javaweb-springboot入门2
55 0
java202303java学习笔记第四十五天javaweb-springboot入门3
java202303java学习笔记第四十五天javaweb-springboot入门3
32 0
java202303java学习笔记第四十五天javaweb-springboot入门1
java202303java学习笔记第四十五天javaweb-springboot入门1
50 0
|
XML 缓存 前端开发
Java学习之路006——Servlet开发
包括引入servlet的api库、IDEA2022配置servlet有关操作,以及servlet的xml配置与注解使用;以及简单的servlet编程实现。
173 0
下一篇
DataWorks