SpringMVC入門案例 & 常用API使用演示
文章目錄
SpringMVC入門案例
SpringMVC的建立方式有xml和配置類兩種方式
這裡只記錄實際應用中使用的方式搭建SpringMVC工程
檔案結構
步驟概述
- 因為採用父級工程和子工程的方式進行演示,所以此處只對父級pom.xml檔案進行修改,新增子工程需要的依賴包以及jdk版本
- 構建配置類WebConfig,掃描Controller層
- 編輯controller層,對頁面請求進行處理
- 構建啟動類,該啟動類繼承了AbstractAnnotationConfigDispatcherServletInitializer,並通過其下的三個函式對配置類進行解析
- 編寫需要的前端頁面
步驟實現
- 父級pom.xml的修改
<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>com.dean</groupId>
<artifactId>SpringMvcAPi</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>mvc-viewResolution</module>
</modules>
<packaging>pom</packaging>
<name>SpringMvcAPi</name>
<url>http://maven.apache.org</url>
<!--1、修改父級的pom.xml檔案 只需要修改properties和dependencies節點的內容-->
<!--修改版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!--新增所有子工程可能用到的依賴包-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
- 構建web配置類WebConfig
@ComponentScan("com.dean.controller")
public class WebConfig {
}
- 編輯前端控制器 controller層
@Controller //將bean注入到Spring容器
@RequestMapping("/user") //配置請求對映,在請求時用來區分不同的controller
public class UserController {
//返回頁面有兩種寫法
//1、返回頁面的檔名,作為字串,框架會呼叫ModelAndView進行返回檢視
//實際請求拼接了/user和/hello 從而找到hello方法
@RequestMapping("/hello")
public String hello()
{
return "/hello.jsp";
}
//2、直接設定返回值為ModelAndView
@RequestMapping("/view")
public ModelAndView view()
{
return new ModelAndView("/view.jsp");
}
}
- 編寫啟動類
public class WebMvcInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//整合Spring使用的,這裡暫不配置
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
//指定SpringMvc的配置類
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//配置請求對映,這裡配置所有請求,即/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
- 編寫前端頁面 index(主頁)hello(/user/hello請求頁面)view(/user/view請求頁面)
index
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%--5、編寫前端頁面 index主頁--%>
<title>主頁</title>
</head>
<body>
<h1>
<a href="/user/hello">hello</a>
</h1>
<h1>
<a href="/user/view">view</a>
</h1>
</body>
</html>
hello
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%--5、編寫前端頁面 hello--%>
<title>Hello</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
view
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%--5、編寫前端頁面 view--%>
<title>View</title>
</head>
<body>
<h1>View</h1>
</body>
</html>
常用API
檢視解析
檢視解析實質上是利用對方法的後置攔截,在返回檢視時進行配置檢視解析器,使得在controller層返回引數的時候,只需要返回檢視名稱,而無需返回字尾名等
具體實現
在上述專案的WebConfig類中注入InternalResourceViewResolver
@ComponentScan("com.dean.controller")
public class WebConfig {
//新增檢視解析器
@Bean
public InternalResourceViewResolver viewResolver()
{
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
//設定檢視路徑字首
viewResolver.setPrefix("/");
//設定檢視路徑的字尾
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
controller層的程式碼返回值的更改
@Controller //將bean注入到Spring容器
@RequestMapping("/user") //配置請求對映,在請求時用來區分不同的controller
public class UserController {
@RequestMapping("/hello")
public String hello()
{
//配置檢視解析器之前
//return "/hello.jsp";
//配置檢視解析器後
return "hello";
}
@RequestMapping("/view")
public ModelAndView view()
{
//配置檢視解析器之前
//return new ModelAndView("/view.jsp");
//配置檢視解析器之後
return new ModelAndView("view");
}
}
檢視解析器會使springmvc獲取到controller方法的返回值,然後與字首字尾拼接得到完整的檢視路徑
但上述的檢視解析器配置的是放在根路徑下,從外部可以直接訪問,在安全性上較差,servlet對此有所改進,將檢視放在WEB-INF目錄下,在該目錄下的檢視只能從內部訪問,而無法從外部直接訪問
改進後的檔案結構如下:
改進後的檢視解析器程式碼如下:
@ComponentScan("com.dean.controller")
public class WebConfig {
//新增檢視解析器
@Bean
public InternalResourceViewResolver viewResolver()
{
InternalResourceViewResolver viewResolver=
new InternalResourceViewResolver();
//直接放在根目錄下不安全,改進版
//設定檢視路徑字首
viewResolver.setPrefix("/WEB-INF/view/");
//設定檢視路徑字尾
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
引數傳遞(等同於servlet中的request.getAttribute())
在Servlet中引數的傳遞通過request.getAttribute()方法,返回值是string,使用時需要自行轉換
springMvc簡化了這一過程,具有自動引數轉化功能
基本資料型別 & String型別
主要核心程式碼在Controller層
@Controller
@RequestMapping("/user")
public class UserController {
//value是請求對映
//method是請求方法 類似servlet的doPost方法
@RequestMapping(value = "/addUser",method = RequestMethod.POST)
public ModelAndView addUser(
//@RequestParam 說明該引數是請求引數
//name 指明引數名稱 與表單中標籤的名稱一致 未指定時預設與形參變數名相同
//required 確定引數是否必須傳遞 未指定時預設為true
//defaultValue 當引數不是一定要傳遞時,可以設定引數的預設值
@RequestParam(name="username",required = true) String name,
@RequestParam(required = false,defaultValue = "21") Integer age,
String phone
)
{
System.out.println(name+"\t"+age+"\t"+phone);
return new ModelAndView("success");
}
}
請求頁面使用表單完成
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主頁</title>
</head>
<body>
<h1>基本資料型別 & String</h1>
<form action="/user/addUser" method="post">
<p>
<label for="username">username:</label>
<input type="text" id="username" name="username">
</p>
<p>
<label for="age">age:</label>
<input type="text" id="age" name="age">
</p>
<p>
<label for="phone">phone:</label>
<input type="text" id="phone" name="phone">
</p>
<button type="submit">add</button>
</form>
</body>
</html>
物件型別(自動裝箱)
當傳遞的引數是自定義的物件型別時,SpringMVC採用了自動裝箱技術,會去自動匹配POJO型別(pojo是簡單java物件,即javaBean,只是叫了不同的名字)
物件型別Pet
public class Pet {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Pet{" +
"name='" + name + '\'' +
'}';
}
}
Person類
public class Person {
private String name;
private Integer age;
private Pet pet;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Pet getPet() {
return pet;
}
public void setPet(Pet pet) {
this.pet = pet;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", pet=" + pet +
'}';
}
}
Controller
@Controller
@RequestMapping("/user")
public class UserController {
//物件型別自動裝箱
@RequestMapping(value = "/addPerson",method = RequestMethod.POST)
public ModelAndView addPerson(
/*
會去自動找Person類,呼叫setter方法
*/
Person person
)
{
System.out.println(person);
return new ModelAndView("success");
}
}
前端頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主頁</title>
</head>
<body>
<h1>物件型別 自動裝箱</h1>
<form action="/user/addPerson" method="post">
<p>
<label for="name">Person-name:</label>
<input type="text" name="name" id="name">
</p>
<p>
<label for="age">Age:</label>
<input type="text" name="age" id="age">
</p>
<p>
<label for="pet-name">Pet-name:</label>
<input type="text" name="pet.name" id="pet-name">
</p>
<button type="submit">add</button>
</form>
</body>
</html>
日期型別
針對日期型別,主要依靠兩個註解
@EnableWebMvc 和 @DateTimeFormat
兩步搞定
1、在WebConfig上新增註解@EnableWebMvc
2、在形參或成員變數上新增註解@DateTimeFormat
具體程式碼如下:
WebConfig
@ComponentScan("com.dean.controller")
@EnableWebMvc //開啟轉換器 便於將表單提交的String型別的資料轉換為Date型別
public class WebConfig {
@Bean
public InternalResourceViewResolver viewResolver()
{
InternalResourceViewResolver resolver=new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
}
UserController
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/date",method = RequestMethod.GET)
public ModelAndView getDate(@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date)
{
System.out.println(date);
return new ModelAndView("success");
}
}
前端頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主頁</title>
</head>
<body>
<h1>日期型別</h1>
<form action="/user/date" method="get">
<p>
<label for="date">Date:</label>
<input type="text" id="date" name="date">
</p>
<button type="submit">submit</button>
</form>
</body>
</html>
引數亂碼
在web的啟動類處新增過濾器Filter進行編碼設定
返回引數(等同於servlet中的request.setAttribute(“key”,value))
在servlet裡,通過request.setAttribute()在後端設定引數,在前端頁面通過ER表示式獲取引數的值顯示在介面上
但在SpringMVC中有非常多的方式返回引數,然後在前端頁面通過ER表示式進行渲染資料
方式1:ModelAndView+ModelAndView.addObject()
程式碼如下:
前端頁面:
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="false" %>
<%--使用ER表示式 引入taglib--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<%--6、前端頁面 返回頁面--%>
<title>返回頁面</title>
</head>
<body>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${users}">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.age}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
前端控制器:
@Controller
@RequestMapping("/user")
public class UserController {
//addObject方式
@RequestMapping("/find-one")
public ModelAndView findOne()
{
//使用list模擬資料庫資料
List<User> users=new ArrayList<>();
users.add(new User("1", "小海", 22));
users.add(new User("2", "小白", 18));
users.add(new User("3", "zz", 26));
users.add(new User("4","鯨魚",28));
ModelAndView mv=new ModelAndView();
//相當於request.setAttribute("users",users);
mv.addObject("users",users);
//設定返回檢視
mv.setViewName("userView");
return mv;
}
}
方式2:ModelAndView+Model.addAttribute()
前端頁面與上述一致
前端控制器程式碼如下:
@Controller
@RequestMapping("/user")
public class UserController {
//addAtribute方式
@RequestMapping("/find-two")
public ModelAndView findTwo(Model model)
{
//使用list模擬資料庫資料
List<User> users=new ArrayList<>();
users.add(new User("1", "小海", 22));
users.add(new User("2", "小白", 18));
users.add(new User("3", "zz", 26));
users.add(new User("4","鯨魚",28));
//依然是request.setAttribute("users",users);
model.addAttribute("users",users);
//返回檢視
return new ModelAndView("userView","model",model);
}
}
方式3:ModelAndView+Map
前端頁面與上述一致
前端控制器程式碼如下:
@Controller
@RequestMapping("/user")
public class UserController {
//ModelAndView+Map
@RequestMapping("/find-three")
public ModelAndView findThree(Map<String, Object> map)
{
//使用list模擬資料庫資料
List<User> users=new ArrayList<>();
users.add(new User("1", "小海", 22));
users.add(new User("2", "小白", 18));
users.add(new User("3", "zz", 26));
users.add(new User("4","鯨魚",28));
//將資料放入map
map.put("users",users);
//返回檢視
return new ModelAndView("userView",map);
}
}
方式4:String+Map
前端頁面與之前一致
前端控制器程式碼如下:
@Controller
@RequestMapping("/user")
public class UserController {
//String+Map
@RequestMapping("/find-four")
public String findFour(Map<String, Object> model)
{
//使用list模擬資料庫資料
List<User> users=new ArrayList<>();
users.add(new User("1", "小海", 22));
users.add(new User("2", "小白", 18));
users.add(new User("3", "zz", 26));
users.add(new User("4","鯨魚",28));
//將資料放入map
model.put("users",users);
return "userView";
}
}
方式5:Web原生物件:傳遞形參(HttpServletRequest,HttpServletResponse)
前端頁面程式碼同上
前端控制器程式碼如下:
@Controller
@RequestMapping("/user")
public class UserController {
//Web原生物件 傳參
@RequestMapping("/find-web")
public String findWeb(HttpServletRequest req, HttpServletResponse resp)
{
//使用list模擬資料庫資料
List<User> users=new ArrayList<>();
users.add(new User("1", "小海", 22));
users.add(new User("2", "小白", 18));
users.add(new User("3", "週週", 26));
users.add(new User("4","鯨魚",28));
//使用Web原生物件HttpServletRequest設定引數
req.setAttribute("users",users);
return "userView";
}
}
方式6:Web原生物件:建立ServletRequestAttributes
通過自行建立ServletRequestAttributes物件獲取原生引數
前端頁面程式碼同上
前端控制器程式碼如下:
@Controller
@RequestMapping("/user")
public class UserController {
//建立ServletRequestAttributes物件
@RequestMapping("/webObj")
public String webObj()
{
//使用list模擬資料庫資料
List<User> users=new ArrayList<>();
users.add(new User("1", "週週", 26));
users.add(new User("2","鯨魚",28));
users.add(new User("3", "小海", 22));
users.add(new User("4", "小白", 18));
ServletRequestAttributes requestAttributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//通過ServletRequestAttributes例項獲取引數物件
//ServletRequestAttributes可以獲取HttpServletRequest HttpServletResponse HttpSession物件
HttpServletRequest req = requestAttributes.getRequest();
//通過request設定引數
req.setAttribute("users",users);
//返回檢視
return "userView";
}
}
JSON資料處理
核心步驟
- pom.xml檔案中新增json的依賴包
- WebConfig中新增@EnableWebMvc 並配置不要將靜態資源的載入當作請求
- 在controller層新增註解 @ResponseBody 並編寫方法進行傳遞資料
- 在前端頁面引入jquery並編寫Ajax請求
具體實現
- pom.xml新增的依賴包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.0-rc2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.0-rc2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.0-rc2</version>
</dependency>
- WebConfig程式碼
@ComponentScan("com.dean.controller")
@EnableWebMvc //一定要新增
public class WebConfig implements WebMvcConfigurer {
//新增預設請求的檢視返回 可以沒有
//即請求/時 返回index.html頁面
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
//配置靜態資源
//使載入靜態資源時,不被當作請求處理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
- Controller層程式碼
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/findUser",method = RequestMethod.POST)
@ResponseBody //幫助使用HttpServletResponse返回資料
//採用形參傳參,前端頁面設定的引數將會傳到後端
public List<User> findUser(User user)
{
//前端Ajax請求的資料
System.out.println(user);
//後端傳送的資料
List<User> users=new ArrayList<>();
users.add(new User("1", "週週", 26));
users.add(new User("2", "小海", 22));
users.add(new User("3", "小白", 18));
return users;
}
}
- 前端頁面
前端頁面會返回一個包含後端傳入資料的表格
<!DOCTYPE html>
<html lang="en">
<head>
<!--6、編寫前端頁面-->
<meta charset="UTF-8">
<title>主頁</title>
<!--引入jquery-->
<script src="/static/jquery-2.1.1.js"></script>
</head>
<body>
<h1>Html</h1>
<button onclick=findUser()>findUser</button>
<table id="table">
</table>
<script>
function findUser() {
$.ajax({
url:"/user/findUser",
method:"post",
dataType:"json",
data:{id:4,name:"鯨魚",age:22},
success:function (data) {
//$('#table').empty(); //清空原表格
$('#table').append("<tr><th>id</th><th>name</th><th>age</th></tr>");
// let html="<tr><th>id</th><th>name</th><th>age</th></tr>";
$.each(data,function (i,item) {
html="<tr>" +
"<td>"+item['id']+"</td>"+
"<td>"+item['name']+"</td>"+
"<td>"+item['age']+"</td>"+
"</tr>"
$('#table').append(html);
});
// $('#table').html(html);
}
})
}
</script>
</body>
</html>
RestFul請求
將前後端分離,在處理請求時,後端只返回資料(即只提供資源)給前端頁面,只渲染資料,不再渲染標籤
前端和後端設定不同的埠號,部署在不同的伺服器上
RestFul的狀態轉換(GET POST Delete Put)對應著對於資源的CRUD操作
RestFul中有一個重要的概念:冪等性(即無論請求多少次,資源都是相同的)
核心步驟
- 在專案的pom.xml中新增依賴
- 編寫Spring MVC的配置類 (核心 @EnableWebMvc)
- 編寫前端控制器 UserController,開啟同源策略,編寫請求 (核心 **@CrossOrigin ** @GetMapping @PostMapping @PutMapping @DeleteMapping 或 @RequestMapping+@ResponseBody )
- 模擬資料,設計響應資料的格式
- 編寫啟動類
- 使用WebStorm編寫前端頁面
- 將前端頁面部署到nginx上
具體實現
後端
檔案結構
- 修改pom.xml
- SpringMvc配置類
@ComponentScan("com.dean.controller")
@EnableWebMvc
public class WebConfig {
}
- 前端控制器
新增的註釋
Get請求
@Controller+@ResponseBody版本
//Get請求
//url: /user/1 (查詢id=1的使用者資訊)
//響應型別: application/json
//返回資料:{"id":1,"name":"string","age":int}
@RequestMapping(value = "{id}",method = RequestMethod.GET)
@ResponseBody
public ResultEntity getUserById(@PathVariable(value = "id") String id)
{
//從資料庫請求資料
User user=users.get(id);
return new ResultEntity(200,"ok",true,user);
}
@RestController版本
//Get請求
//url: /user/1 (查詢id=1的使用者資訊)
//響應型別: application/json
//返回資料:{"id":1,"name":"string","age":int}
@GetMapping("{id}") //等同於@RequestMapping(value = "{id}",method = RequestMethod.GET)
public ResultEntity getUserById(@PathVariable(value = "id") String id)
{
//從資料庫請求資料
User user=users.get(id);
return new ResultEntity(200,"ok",true,user);
}
Post請求
@Controller+@ResponseBody版本
//Post請求
//url: /user 新增一個使用者
//引數型別:application/json
//引數: {"id":1,"name":"string","age":int} 自動裝箱
//響應型別:application/json
//響應資料:{}
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ResultEntity addUser(@RequestBody User user)
{
users.put(user.getId(),user);
System.out.println(user);
return new ResultEntity(200,"ok",true,null);
}
@RestController版本
//Post請求
//url: /user 新增一個使用者
//引數型別:application/json
//引數: {"id":1,"name":"string","age":int} 自動裝箱
//響應型別:application/json
//響應資料:{}
@PostMapping
public ResultEntity addUser(@RequestBody User user)
{
users.put(user.getId(),user);
System.out.println(user);
return new ResultEntity(200,"ok",true,null);
}
Put請求
@Controller+@ResponseBody版本
//Put請求
//url: /user/1 修改id=1的使用者資訊
//引數型別:application/json
//引數格式:{"name":"string","age":int}
//響應型別:application/json
//響應資料:{}
@RequestMapping(value = "{id}",method = RequestMethod.PUT)
@ResponseBody
public ResultEntity updateUser(@PathVariable String id,@RequestBody User user)
{
user.setId(id);
users.put(id,user);
System.out.println(users);
return new ResultEntity(200,"update success",true,"{}");
}
@RestController版本
//Put請求
//url: /user/1 修改id=1的使用者資訊
//引數型別:application/json
//引數格式:{"name":"string","age":int}
//響應型別:application/json
//響應資料:{}
@PutMapping("{id}")
public ResultEntity updateUser(@PathVariable String id,@RequestBody User user)
{
user.setId(id);
users.put(id,user);
System.out.println(users);
return new ResultEntity(200,"update success",true,"{}");
}
Delete請求
@Controller+@ResponseBody版本
//Delete請求
//url: /user/1 刪除id=1的使用者
//響應型別:application/json
//響應資料:{}
@RequestMapping(value = "{id}",method = RequestMethod.DELETE)
@ResponseBody
public ResultEntity delUser(@PathVariable(value = "id") String uid)
{
users.remove(uid);
return new ResultEntity(200,"delete success",true,"{}");
}
@RestController版本
//Delete請求
//url: /user/1 刪除id=1的使用者
//響應型別:application/json
//響應資料:{}
@DeleteMapping("{id}") //等同於@RequestMapping(value = "{id}",method = RequestMethod.DELETE)
public ResultEntity delUser(@PathVariable(value = "id") String uid)
{
users.remove(uid);
return new ResultEntity(200,"delete success",true,"{}");
}
- 模擬資料User 設計響應資料格式
User
public class User {
private String id;
private String name;
private Integer age;
public User() {
}
public User(String id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
響應資料格式(仿照http的響應資料格式)
/**
* {
* "code":200, 狀態碼
* "message":"string", 提示資訊
* "flag":"boolean", 執行狀況
* "data":"object(json)" 資料
* }
*/
public class
ResultEntity {
private Integer code;
private String message;
private Boolean flag;
private Object data;
public ResultEntity() {
}
public ResultEntity(Integer code, String message, Boolean flag, Object data) {
this.code = code;
this.message = message;
this.flag = flag;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Boolean getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
- 啟動類
public class WebServerInit extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
前端
- 引入vue.js和jquery.js
- 編寫前端介面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主頁</title>
<!--引入jquery和vue-->
<script src="./static/vue.js"></script>
<script src="./static/jquery-2.1.1.js"></script>
</head>
<body>
<div id="app">
<!--顯示所有使用者-->
<table style="width: 500px;text-align: center;border-color: cornflowerblue" border="1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users" :key="user.id">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.age }}</td>
</tr>
</tbody>
</table>
<!--新增使用者-->
<div id="add-user">
<p>
<label for="add-user-id">id:</label>
<input type="text" id="add-user-id" v-model="addUser.id">
</p>
<p>
<label for="add-user-name">name:</label>
<input type="text" id="add-user-name" v-model="addUser.name">
</p>
<p>
<label for="add-user-age">age:</label>
<input type="text" id="add-user-age" v-model="addUser.age">
</p>
<button @click="_addUser()">addUser</button>
<button @click="_updateUser()">updateUser</button>
</div>
<hr>
<p>
<label for="del-user-id">id:</label>
<input type="text" id="del-user-id" v-model="addUser.id">
</p>
<button @click="_deleteUser">deleteUser</button>
</div>
<script>
let vm=new Vue({
el:"#app",
data:{
users:[],
addUser:{
id:"",
name:"",
age:""
}
},
//生命鉤子
created(){
//查詢所有使用者
this._findAllUsers();
},
methods:{
//查詢所有使用者
_findAllUsers(){
let this_=this;
//編寫ajax請求
$.ajax({
url:"http://localhost:8090/user/", //請求url
method:"get",
dataType:"json", //返回資料格式
contentType:"application/json", //網頁檔案的型別和網頁編碼格式
success:function (resp) {
this_.users=resp.data;
}
})
return null;
},
//新增使用者
_addUser(){
let this_=this;
//編寫ajax請求
$.ajax({
url:"http://localhost:8090/user/",
method:"post",
data:JSON.stringify(this_.addUser), //將引數物件轉換為Json格式
dataType:"json",
contentType:"application/json",
success:function (resp) {
this_._findAllUsers(); //重新整理頁面
}
})
},
//修改使用者
_updateUser(){
let id=this.addUser.id;
let user={
name:this.addUser.name,
age:this.addUser.age
}
let this_=this;
//編寫ajax請求
$.ajax({
url:"http://localhost:8090/user/"+id,
method:"put",
data:JSON.stringify(user), //將引數物件轉換為Json格式
dataType:"json",
contentType:"application/json",
success:function (resp) {
this_._findAllUsers(); //重新整理頁面
}
})
},
//刪除使用者
_deleteUser()
{
let id=this.addUser.id;
let this_=this;
//編寫ajax請求
$.ajax({
url:"http://localhost:8090/user/"+id,
method:"delete",
data:JSON.stringify(this_.addUser), //將引數物件轉換為Json格式
dataType:"json",
contentType:"application/json",
success:function (resp) {
this_._findAllUsers(); //重新整理頁面
}
})
}
}
})
</script>
</body>
</html>
- 將頁面部署在nginx上
即將頁面和static檔案複製在nginx的html資料夾裡,刪除原有的index.html檔案
統一異常處理
核心步驟
- controller裡模擬丟擲異常
- 編寫統一異常處理器CustomException
- WebConfig(配置類),WebServerInit(啟動類)和之前一致
具體實現
- Controller
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("main")
public ModelAndView getMain(String name, Model model)
{
if("admin".equals(name))
{
//模擬丟擲異常
throw new RuntimeException("不能使用admin登入");
}
model.addAttribute("name",name);
return new ModelAndView("main");
}
}
- 統一異常處理器CustomException
@ControllerAdvice
public class CustomException {
//指定處理RuntimeException類的異常
@ExceptionHandler(RuntimeException.class)
public ModelAndView exception (Exception e, Model model)
{
System.out.println(e.getMessage());
model.addAttribute("message",e.getMessage());
return new ModelAndView("error");
}
}
攔截器
Filter:過濾器 過濾的是url
intercepter:攔截器 面向方法的代理模式
主要是WebConfig和自定義的攔截器UserInterceptor
- WebConfig
@ComponentScan("com.dean.controller")
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
//新增檢視解析器
@Bean
public InternalResourceViewResolver viewResolver()
{
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
//配置靜態資源
//相當於xml中的<mvc:default-servlet-handler>
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//新增攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//建立一個自定義的攔截器,加入容器
registry.addInterceptor(new UserInterceptor());
}
}
- UserInterceptor
public class UserInterceptor implements HandlerInterceptor {
//controller目標方法之前執行
//適合做許可權的控制
//形參Object handler實際指的是目標方法物件
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod method= (HandlerMethod) handler;
//method.getMethod().getName() 獲取到目標方法名
System.out.println("目標方法執行前"+method.getMethod().getName());
return true;
}
//controller目標方法成功執行之後執行
//適合做日誌的管理
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//modelAndView.getViewName() 獲取到返回的頁面名
System.out.println("目標方法成功執行之後"+modelAndView.getViewName());
}
//最終方法,目標方法執行結束後(不論是否丟擲異常)
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//ex.getMessage() 獲取到異常資訊
System.out.println("目標方法執行之後"+ex.getMessage());
}
}
Struts2
SpringMvc是基於方法開發的,較快,通過形參傳參,可以進行單例開發
Struts2是基於類開發的,較慢,通過類的成員變數傳參,無法進行單例開發
雖然很少有人用,但瞭解還是要了解的
核心步驟
- pom.xml中新增依賴
- 編寫配置類web.xml
- 編寫核心類Action
- 編寫核心檔案,配置請求返回檢視,struts.xml
- 編寫前端頁面
具體實現
-
pom.xml中新增依賴
-
編寫配置類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_3_1.xsd"
version="3.1">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- 編寫核心類Action
public class UserAction {
//基於類的程式設計 引數通過成員變數傳遞
public String message;
public void setMessage(String message) {
this.message = message;
}
public String hello()
{
System.out.println(message);
return "SUCCESS";
}
public String login()
{
if("admin".equals(message))
return "ERROR";
return "SUCCESS";
}
}
- 編寫核心檔案,配置請求返回檢視,struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- 請求引數的編碼方式 -->
<constant name="struts.i18n.encoding" value="utf-8"/>
<package name="USER" extends="struts-default" namespace="/user"> <!--請求由namespace和name拼接組成-->
<action name="hello" class="com.dean.action.UserAction" method="hello"> <!--和action中的方法對應-->
<result name="SUCCESS">/main.jsp</result> <!--配置返回頁面-->
</action>
<action name="login" class="com.dean.action.UserAction" method="login">
<result name="SUCCESS">/main.jsp</result>
<result name="ERROR">/error.jsp</result>
</action>
</package>
</struts>
- 編寫前端頁面
index首頁
成功返回頁面
發生錯誤後返回的頁面
相關文章
- praat使用入門演示
- RocketMQ系列一:入門級使用演示MQ
- SpringMVC 入門SpringMVC
- SpringMVC入門SpringMVC
- springmvc入門登入功能SpringMVC
- OpenGL/OpenGL ES入門:紋理初探 - 常用API解析API
- SpringMVC入門學習---使用註解開發SpringMVC
- SpringMVC(1)- 入門案例、基本配置、請求、響應、Servlet相關介面SpringMVCServlet
- kafka入門案例Kafka
- RabbitMQ入門案例MQ
- vuex入門案例Vue
- Elasticsearch 入門實戰(8)--REST API 使用二(Search API)ElasticsearchRESTAPI
- GDAL API入門API
- SpringMVC 入門、請求、響應SpringMVC
- SpringMVC入門與環境搭建SpringMVC
- SpringMVC簡單搭建與入門SpringMVC
- Python入門(案例)Python
- 前端-vue入門案例前端Vue
- CSS入門案例:摺扇CSS
- jQuery入門(四)案例jQuery
- FineBI入門案例分析
- 熱門的常用 API 大全分享API
- 常用的熱門 API 大全分享API
- 微信小程式入門教程之四:API 使用微信小程式API
- Java Json API:Gson使用簡單入門JavaJSONAPI
- Elasticsearch-02-入門:叢集、節點、分片、索引及常用APIElasticsearch索引API
- zookeeper入門(3)API常用函式功能與引數詳解API函式
- SpringMVC:RESTful案例SpringMVCREST
- 小白入門使用Nginx基礎的常用操作Nginx
- iOS架構入門 - MVC模式例項演示iOS架構MVC模式
- springmvc簡單學習(一)-----入門SpringMVC
- SpringMVC入門就這麼簡單SpringMVC
- Elasticsearch 入門實戰(9)--Java API Client 使用二ElasticsearchJavaAPIclient
- RabbitMQ 入門案例 - fanout 模式MQ模式
- spring 01 入門案例Spring
- Flask服務入門案例Flask
- Web API--入門--(一)ASP.NET Web API 2(C#)入門WebAPIASP.NET
- 《SpringMVC從入門到放肆》十五、SpringMVC之上傳檔案SpringMVC