目次
springmvcアドバンスト
メインコンテンツ:
ajax非同期インタラクション
デフォルトでは、SpringmvcはMappingJackson2HttpMessageConverterを使用してjsonデータを変換します。これは、Jacksonパッケージに追加する必要があります。同時に、<mvc:annotation-driven />を使用します。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
1.1 @RequestBody
このアノテーションは、Controllerメソッドの正式なパラメーター宣言に使用されます。ajaxを使用して送信され、contentTypeをjsonとして指定すると、HttpMessageConverterインターフェイスを介して対応するPOJOオブジェクトに変換されます。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--引入js资源, 注意下面的script标签不要自闭合, 否则后面的显示不出来--%>
<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
<%--ajax异步交互--%>
<button id="btn1">ajax异步提交</button>
<script>
$("#btn1").click(function () {
let url = '${pageContext.request.contextPath}/user/ajaxRequest';
let data = '[{"id":1,"username":"张三"},{"id":2,"username":"李四"}]';
$.ajax({
type: 'POST',
url: url,
data : data,
contentType : 'application/json;charset=utf-8',
success: function (resp) {
alert(JSON.stringify(resp));
}
})
})
</script>
</body>
</html>
/*
ajax异步交互 [{"id":1,"username":"张三"},{"id":2,"username":"李四"}]
*/
@RequestMapping("/ajaxRequest")
public void ajaxRequest(@RequestBody List<User> list){
System.out.println(list);
}
1.2 @ResponseBody
このアノテーションは、Controllerメソッドによって返されたオブジェクトをjson、xmlなどのHttpMessageConverterインターフェイスを介して指定された形式のデータに変換し、Responseを介してクライアントに応答するために使用されます。
/*
ajax异步交互 [{"id":1,"username":"张三"},{"id":2,"username":"李四"}]
*/
@RequestMapping("/ajaxRequest")
@ResponseBody
public List<User> ajaxRequest(@RequestBody List<User> list){
System.out.println(list);
return list;
}
2つのRESTful
2.1RESTfulとは
Restfulは、ソフトウェアアーキテクチャスタイルと設計スタイルであり、標準ではありません。一連の設計原則と制約を提供するだけです。主にクライアント/サーバー相互作用ソフトウェアに使用されますが、このスタイルに基づいて設計されたソフトウェアは、より簡潔で、より階層化され、キャッシュメカニズムの実装が容易になります。
Restfulスタイルのリクエストは「url + requestmode」を使用してリクエストの目的を示します。動作モードを示すHTTPプロトコルの4つの動詞は次のとおりです。
- GET:読む
- POST:作成
- PUT:更新(更新)
- DELETE:删除(Delete)
2.2コードの実装
@PathVariable
RESTfulリクエストアドレスのプレースホルダーの値を受け取るために使用されます
package com.lagou.controller;
@Controller
@RequestMapping("/restful")
public class RestfulController {
/*
根据id进行查询
localhost:8080/项目名/restful/user/2 + get请求方式 404 findById:2
*/
// 下面的method表示只能用get方式请求, {...}是个占位符, 里面写参数名称
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
public String findById(@PathVariable Integer id){
// 调用service方法完成对id为2的这条记录的查询
// 问题:findById方法中怎么才能获取restful编程风格中url里面占位符的值
// 使用 PathVariable注解 获取占位符的值, 如上 ↑
return "findById: "+ id ;
}
}
@RestController
RESTfulスタイルは主にフロントエンドとバックエンドの分離プロジェクト開発に使用されます。フロントエンドはajaxを介してサーバーと非同期に対話します。プロセッサは通常jsonデータを返すため、@ RestControllerを使用して2つのアノテーション@Controllerと@を置き換えます。 ResponseBody。
package com.lagou.controller;
@RestController //这是个组合主键:组合@Controller + @ResponseBody
@RequestMapping("/restful")
public class RestfulController {
/*
根据id进行查询
localhost:8080/项目名/restful/user/2 + get请求方式 404 findById:2
*/
// 下面的GetMapping表示只能用get方式请求, {...}是个占位符, 里面写参数名称
@GetMapping("/user/{id}") // @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
//@ResponseBody // 该注解会把return后面的直接以字符串形式返回给浏览器, 而不走视图解析器
public String findById(@PathVariable Integer id){
// 调用service方法完成对id为2的这条记录的查询
// 问题:findById方法中怎么才能获取restful编程风格中url里面占位符的值
// 使用 PathVariable注解 获取占位符的值, 如上 ↑
return "findById: "+ id ;
}
/*
新增方法
*/
// 下面的PostMapping就表示后面的一长串
@PostMapping("/user") // @RequestMapping(value = "/user",method = RequestMethod.POST)
public String post(){
// 新增
return "post";
}
/*
更新方法
*/
@PutMapping("/user")
public String put(){
// 更新操作
return "put";
}
/*
删除方法
*/
@DeleteMapping("/user/{id}")
public String delete(@PathVariable Integer id){
return "delete" + id;
}
}
}
3つのファイルのアップロード
3.1ファイルアップロードの3つの要素
- フォームアイテムtype = "file"
- フォーム送信メソッドmethod = "POST"、リクエスト本文はありますか
- フォームのenctype属性はマルチパートフォームenctype = "multipart / form-data"です。
3.2ファイルアップロードの原則
フォームフォームがマルチパートフォームに変更されると、request.getParameter()は無効になります。
フォームのenctypeがapplication / x-www-form-urlencodedの場合、フォーム
の本文コンテンツの形式は次のとおりです。name = value&name = value
フォームのenctype値がmutilpart / form-dataの場合、リクエスト本文のコンテンツはマルチパートフォームになります。
3.3単一ファイルのアップロード
ステップ分析
1)pom.xmlインポートファイルアップロードとio座標
<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)Spring-mvc構成ファイルアップロードパーサー
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定文件上传的最大值为5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
<!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
<property name="maxInMemorySize" value="40960"></property>
</bean>
3)ファイルアップロードコードを書く
<%--
Created by IntelliJ IDEA.
User: Szc.0713
Date: 2020/6/24
Time: 16:35
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>
<%--编写一个满足文件上传三要素的表单
1.表单的提交方式必须是post
2.表单的enctype属性必须要修改成multipart/form-data
3.表单中必须要有文件上传项
--%>
<form action="${pageContext.request.contextPath}/fileupload" method="post" enctype="multipart/form-data">
名称:<input type="text" name="username"> <br>
文件:<input type="file" name="filePic"> <br>
<input type="submit" value="单文件上传">
</form>
</body>
</html>
package com.lagou.controller;
@Controller
public class FileUploadController {
/*
单文件上传
*/
// 上传文件类型为下面的multipartfile
@RequestMapping("/fileupload")
public String fileUpload(String username, MultipartFile filePic) throws IOException {
//获取表单的提交参数,完成文件上传
System.out.println(username);
// 获取原始的文件上传名 a.txt abc
String originalFilename = filePic.getOriginalFilename();
filePic.transferTo(new File("D:/upload/"+originalFilename));
return "success";
}
}
3.4複数ファイルのアップロード
<%--
Created by IntelliJ IDEA.
User: Szc.0713
Date: 2020/6/24
Time: 16:35
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>
<%--编写一个满足文件上传三要素的表单
1.表单的提交方式必须是post
2.表单的enctype属性必须要修改成multipart/form-data
3.表单中必须要有文件上传项
--%>
<%--实现多文件上传--%>
<form action="${pageContext.request.contextPath}/filesupload" method="post" enctype="multipart/form-data">
名称:<input type="text" name="username"> <br>
文件1:<input type="file" name="filePic"> <br>
文件2:<input type="file" name="filePic"> <br>
<input type="submit" value="多文件上传">
</form>
</body>
</html>
/*
多文件上传
*/
@RequestMapping("/filesupload")
public String filesUpload(String username, MultipartFile[] filePic) throws IOException {
//获取表单的提交参数,完成文件上传
System.out.println(username);
// 获取原始的文件上传名 a.txt abc
for (MultipartFile multipartFile : filePic) {
String originalFilename = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("D:/upload/"+originalFilename));
}
return "success";
}
4つの例外処理
4.1例外処理のアイデア
Javaでは、一般に例外を処理する2つの方法があります
。1つは現在のメソッドキャプチャ処理(try-catch)であり、この処理メソッドはビジネスコードと例外処理コードの結合を引き起こします。
もう1つは、それを単独で処理するのではなく、処理(スロー)のために呼び出し元にスローし、呼び出し元が呼び出し元にスローする、つまりスローすることです。
この方法に基づいて、SpringMVCの例外処理メカニズムが導出されます。
以下に示すように、システムのdao、サービス、およびコントローラーはすべて、throws Exceptionを介して上向きにスローされ、最後に、springmvcフロントエンドコントローラーが例外ハンドラーに渡されて例外処理が行われます。
4.2カスタム例外ハンドラ
ステップ分析
1)HandlerExceptionResolverを実装するための例外ハンドラークラスを作成します
package com.lagou.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 全局异常处理类, 实现异常处理器接口
public class GlobalExceptionResolver implements HandlerExceptionResolver {
/*
Exception e:实际抛出的异常对象
*/
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
// 进行具体的异常处理 产生异常后,跳转到一个最终的异常页面
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("error",e.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
2)例外ハンドラーを構成する
<!--配置自定义的异常处理器-->
<bean id="globalExceptionResolver" class="com.lagou.exception.GlobalExceptionResolver"></bean>
3)例外ページを作成する
<%--
Created by IntelliJ IDEA.
User: Szc.0713
Date: 2020/6/21
Time: 12:26
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>
<h3>success... </h3>
<% System.out.println("视图执行了....");%>
</body>
</html>
4)異常ジャンプをテストする
package com.lagou.controller;
@Controller
public class ExceptionController {
@RequestMapping("/testException")
public String testException(){
int i = 1/0;
return "success";
}
}
4.3Webの例外処理メカニズム
<!--处理404异常
产生异常, 跳转到location-->
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
<!--处理500异常-->
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
5つの迎撃機
5.1インターセプター(インターセプター)の役割
Spring MVCのインターセプターは、サーブレット開発のフィルターに似ており、プロセッサーの前処理と後処理に使用されます。
インターセプターは、インターセプターチェーン(InterceptorChain)と呼ばれるチェーンに特定の順序で接続されます。インターセプトされたメソッドまたはフィールドにアクセスすると、インターセプターチェーン内のインターセプターが前に定義された順序で呼び出されます。インターセプターは、AOPのアイデアを具体的に実現したものでもあります。
5.2インターセプターとフィルターの違い
インターセプターとフィルターの違いを図に示します。
5.3クイックスタート
ステップ分析
1)HandlerInterceptorインターフェースを実装するためのインターセプタークラスを作成します
package com.lagou.interceptor;
public class MyInterceptor1 implements HandlerInterceptor {
/*
preHandle: 在目标方法执行之前 进行拦截 return false:不放行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle....");
return true;
}
/*
postHandle: 在目标方法执行之后,视图对象返回之前,执行的方法
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle....");
}
/*
afterCompletion:在流程都执行完成后,执行的方法
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion....");
}
}
2)インターセプターを構成します
<!--配置拦截器
可以配置多个-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/> <!--对所有controller类里面的所有方法都进行拦截-->
<bean class="com.lagou.interceptor.MyInterceptor1"></bean> <!--采用这个拦截器-->
</mvc:interceptor>
</mvc:interceptors>
3)インターセプターのインターセプト効果をテストします
コントローラの書き込み、コントローラへのリクエストの送信、ページのジャンプ
package com.lagou.controller;
@Controller
public class TargetController {
@RequestMapping("/target")
public String targetMethod(){
System.out.println("目标方法执行了....");
return "success";
}
}
jspページを書く
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>success... </h3>
<% System.out.println("视图执行了....");%>
</body>
</html>
5.4インターセプターチェーン
インターセプターは、開発時に単独で使用することも、複数のインターセプターを同時に使用してインターセプターチェーンを形成することもできます。開発手順は、登録時に複数の登録が登録されることを除いて、単一のインターセプターと同じです。ここでの登録の順序は、インターセプターの実行の順序を表すことに注意してください。
上記と同じように、実行順序をテストするMyHandlerInterceptor2操作を記述します。
<!--配置拦截器
可以配置多个, 配置顺序代表执行顺序-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/> <!--对所有controller类里面的所有方法都进行拦截-->
<bean class="com.lagou.interceptor.MyInterceptor1"></bean> <!--采用这个拦截器-->
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/> <!--对所有controller类里面的所有方法都进行拦截-->
<bean class="com.lagou.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
package com.lagou.interceptor;
public class MyInterceptor2 implements HandlerInterceptor {
/*
preHandle: 在目标方法执行之前 进行拦截 return false:不放行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle2....");
return true;
}
/*
postHandle: 在目标方法执行之后,视图对象返回之前,执行的方法
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle2....");
}
/*
afterCompletion:在流程都执行完成后,执行的方法
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion2....");
}
}
5.5知識の要約
インターセプターの方法は次のとおりです。