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、結構

在這裏插入圖片描述

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}

訪問測試

GET 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

package com.pengshiyu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;

@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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章