springMVC
2023-04-11 08:55:17 7 举报
AI智能生成
无
作者其他创作
大纲/内容
配置流程
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
配置前端控制器
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 局部参数:声明配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<!-- Servlet启动时刻:可选 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 局部参数:声明配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<!-- Servlet启动时刻:可选 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置handelerMapper
<mvc:annotation-driven></mvc:annotation-driven>
配置试图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
配置后端控制器
controller层
接受请求参数
基本类型参数
请求参数和方法的形参 同名
实体收参
请求参数和实体的属性 同名
数组收参
集合收参
路径参数
跳转
转发
return "forward:/views/users.jsp";
return "forward:/forw/test1"; //绝对路径
return "index" //相当于转发
重定向
return "redirect:/redir/test1";//绝对路径
return "redirect:/view/user.jsp";
后端响应值
request域
Map
map.put()
Model
model.addAttribute()
ModelMap
modelMap.addAttribute()
ModelAndView
@RequestMapping("/test")
public ModelAndView testData(){//返回值类型为ModelAndView
//新建ModelAndView对象
ModelAndView mv = new ModelAndView();
// 设置视图名,即如何跳转
mv.setViewName("forward:/index.jsp");
// 增加数据
mv.addObject("age",18);
return mv;
}
public ModelAndView testData(){//返回值类型为ModelAndView
//新建ModelAndView对象
ModelAndView mv = new ModelAndView();
// 设置视图名,即如何跳转
mv.setViewName("forward:/index.jsp");
// 增加数据
mv.addObject("age",18);
return mv;
}
session域
@SessionAttributes(value = {"id","username"}, types = {User.class})
解决静态资源问题
此时,所有访问handler的路径都要以 action结尾!!
<servlet>
<servlet-name>mvc9</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mvc9</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mvc9</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mvc9</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
DispathcerServlet的url-pattern依然采用 "/",但追加配置
<!--
额外的增加一个handler,且其requestMapping: "/**" 可以匹配所有请求,但是优先级最低
所以如果其他所有的handler都匹配不上,请求会转向 "/**" ,恰好,这个handler就是处理静态资源的
处理方式:将请求转会到tomcat中名为default的Servlet
-->
<mvc:default-servlet-handler/>
<!--
额外的增加一个handler,且其requestMapping: "/**" 可以匹配所有请求,但是优先级最低
所以如果其他所有的handler都匹配不上,请求会转向 "/**" ,恰好,这个handler就是处理静态资源的
处理方式:将请求转会到tomcat中名为default的Servlet
-->
<mvc:default-servlet-handler/>
- mapping是访问路径,location是静态资源存放的路径
- 将/html/** 中 /**匹配到的内容,拼接到 /hhh/后
http://..../html/a.html 访问 /hhh/a.html
<mvc:resources mapping="/html/**" location="/hhh/"/>
- 将/html/** 中 /**匹配到的内容,拼接到 /hhh/后
http://..../html/a.html 访问 /hhh/a.html
<mvc:resources mapping="/html/**" location="/hhh/"/>
Json处理
使用流程
导入依赖
<!-- Jackson springMVC默认的Json解决方案选择是 Jackson,所以只需要导入jackson的jar,即可使用。-->
<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-databind</artifactId>
<version>2.9.8</version>
</dependency>
在方法上加注释:
@ResponseBody //将controller类的返回值,转换成json(jackson),并将json响应给客户端。
在类上边加注释,作用于类里所有方法:
@RestController
@ResponseBody //将controller类的返回值,转换成json(jackson),并将json响应给客户端。
在类上边加注释,作用于类里所有方法:
@RestController
注释作用
@JsonProperty()
属性名修改
@JsonIgnore
属性忽略
@JsonInclude(JsonInclude.Include.NON_NULL)
null属性排除
@JsonInclude(JsonInclude.Include.NON_EMPTY)
empty属性排除
@JsonSerialize(using = MySerializer.class)
自定义序列化
public class MySerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double aDouble, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
String s = BigDecimal.valueOf(aDouble).setScale
(2, BigDecimal.ROUND_HALF_UP).toString();
jsonGenerator.writeNumber(s);
}
}
@Override
public void serialize(Double aDouble, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
String s = BigDecimal.valueOf(aDouble).setScale
(2, BigDecimal.ROUND_HALF_UP).toString();
jsonGenerator.writeNumber(s);
}
}
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
日期格式化
异常处理
web.xml配置版本
<error-page>
<error-code>500</error-code>
<location>/500.html</location>
</error-page>
<error-code>500</error-code>
<location>/500.html</location>
</error-page>
本类可用的异常处理
//将此方法加在需要异常处理的类中
@ExceptionHandler
public String resolveException(RuntimeException e) {
System.out.println("ExceptionController01出现异常");
e.printStackTrace();
return "index";
}
@ExceptionHandler
public String resolveException(RuntimeException e) {
System.out.println("ExceptionController01出现异常");
e.printStackTrace();
return "index";
}
全局异常处理
//增加一个自定义类
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView exec(Exception e) {
ModelAndView mav = new ModelAndView();
mav.addObject("errorMsg", e);
mav.setViewName("error");
return mav;
}
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView exec(Exception e) {
ModelAndView mav = new ModelAndView();
mav.addObject("errorMsg", e);
mav.setViewName("error");
return mav;
}
}
拦截器
作用:(不确定)
拦截请求,但不能拦截前端页面
拦截请求,但不能拦截前端页面
执行顺序: preHandle--postHandle--afterCompletion
使用流程
定义拦截器类(实现HandlerInterceptor接口)
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle");
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if (user == null) {
System.out.println("没有登录...");
response.sendRedirect("/day20230331/login.html");
return false;
}else {
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle");
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if (user == null) {
System.out.println("没有登录...");
response.sendRedirect("/day20230331/login.html");
return false;
}else {
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
配置applicationContext.xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>//要拦截的请求
<mvc:exclude-mapping path="/login/log"/>//不拦截的请求
<bean class="com.wsk.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>//要拦截的请求
<mvc:exclude-mapping path="/login/log"/>//不拦截的请求
<bean class="com.wsk.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
上传(本地上传到服务器)
使用流程
导入依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
配置applicationContext.xml(上传解析器)
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>//文件最大字节数
<property name="maxUploadSizePerFile" value="1048576"/>//单个文件最大字节数
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<property name="maxUploadSize" value="10485760"/>//文件最大字节数
<property name="maxUploadSizePerFile" value="1048576"/>//单个文件最大字节数
<property name="defaultEncoding" value="UTF-8"/>
</bean>
前端代码
<form action="upLoad" method="post" enctype="multipart/form-data">
文件:<input type="file" name="file"><br>
<button type="submit">上传</button><br>
</form>
文件:<input type="file" name="file"><br>
<button type="submit">上传</button><br>
</form>
后端代码
@RestController
public class UpLoadController {
@RequestMapping("/upLoad")
public String upLoad(MultipartFile file, HttpSession session) {
String filename = file.getOriginalFilename();//获取文件名
System.out.println("filename="+filename);
String prefix = filename.split("\\.")[0];
String suffix = filename.split("\\.")[1];
String random = UUID.randomUUID().toString();
filename = prefix + random + "." + suffix;
String path = session.getServletContext().getRealPath("/upload");//创建存放目录路径
System.out.println("path="+path);
File file1 = new File(path);
if (!file1.exists()) {
file1.mkdirs();
}
try {
file.transferTo(new File(path, filename));//上传文件
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("上传完成...");
return "index";
}
}
public class UpLoadController {
@RequestMapping("/upLoad")
public String upLoad(MultipartFile file, HttpSession session) {
String filename = file.getOriginalFilename();//获取文件名
System.out.println("filename="+filename);
String prefix = filename.split("\\.")[0];
String suffix = filename.split("\\.")[1];
String random = UUID.randomUUID().toString();
filename = prefix + random + "." + suffix;
String path = session.getServletContext().getRealPath("/upload");//创建存放目录路径
System.out.println("path="+path);
File file1 = new File(path);
if (!file1.exists()) {
file1.mkdirs();
}
try {
file.transferTo(new File(path, filename));//上传文件
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("上传完成...");
return "index";
}
}
下载(服务器下载到本地)
前端代码
<a href="downLoad?name=1.jpg">1.jpg 下载</a><br>//对应服务器里文件的名称
后端代码
@RestController
public class DownLoadController {
@RequestMapping("/downLoad")
public String downLoad(String name, HttpSession session, HttpServletResponse resp) {
String realPath = session.getServletContext().getRealPath("/upload");
File file = new File(realPath, name);//通过名称和存放文件夹获取文件
System.out.println(file.getAbsolutePath());
resp.setHeader("content-disposition","attachment;filename="+name);
try {
ServletOutputStream out = resp.getOutputStream();//获得输出流
FileInputStream in = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(in);
byte[] arr = new byte[1024*50];
int len;
while ((len = bis.read(arr)) != -1) {
out.write(arr, 0, len);
out.flush();
}
System.out.println("下载完成...");
} catch (IOException e) {
e.printStackTrace();
}
return "index";
}
}
public class DownLoadController {
@RequestMapping("/downLoad")
public String downLoad(String name, HttpSession session, HttpServletResponse resp) {
String realPath = session.getServletContext().getRealPath("/upload");
File file = new File(realPath, name);//通过名称和存放文件夹获取文件
System.out.println(file.getAbsolutePath());
resp.setHeader("content-disposition","attachment;filename="+name);
try {
ServletOutputStream out = resp.getOutputStream();//获得输出流
FileInputStream in = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(in);
byte[] arr = new byte[1024*50];
int len;
while ((len = bis.read(arr)) != -1) {
out.write(arr, 0, len);
out.flush();
}
System.out.println("下载完成...");
} catch (IOException e) {
e.printStackTrace();
}
return "index";
}
}
restful风格开发
概念
具体说,就是HTTP协议里面,四个表示操作方式的动词:
GET POST PUT DELETE
它们分别代表着四种基本操作:
GET用来获取资源
POST用来创建新资源
PUT用来更新资源
DELETE用来删除资源
示例:
/order/1 HTTP GET :得到id = 1 的 order
/order/1 HTTP DELETE: 删除 id=1 的order
/order/1 HTTP PUT : 更新id = 1的 order
/order HTTP POST : 新增 order
GET POST PUT DELETE
它们分别代表着四种基本操作:
GET用来获取资源
POST用来创建新资源
PUT用来更新资源
DELETE用来删除资源
示例:
/order/1 HTTP GET :得到id = 1 的 order
/order/1 HTTP DELETE: 删除 id=1 的order
/order/1 HTTP PUT : 更新id = 1的 order
/order HTTP POST : 新增 order
两个核心要求:
- 每个资源都有唯一的标识(URL)
- 不同的行为,使用对应的http-method
- 每个资源都有唯一的标识(URL)
- 不同的行为,使用对应的http-method
如何将post请求转换成其他类型请求
web.xml中配置过滤器
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
前端代码:
<input type="hidden" name="_method" value="PUT">
value里是要转换成的请求类型
<input type="hidden" name="_method" value="PUT">
value里是要转换成的请求类型
<a href="player">查询全部</a><br>
<a href="player/1">查询单个</a><br>
<form action="player" method="post">
<input type="text" name="id" placeholder="id"><br>
<input type="text" name="name" placeholder="name"><br>
<input type="date" name="birth" placeholder="birth"><br>
<button type="submit">新增</button><br>
</form>
<form action="player" method="post">
<input type="hidden" name="_method" value="PUT"><br>
<input type="text" name="id" placeholder="id"><br>
<input type="text" name="name" placeholder="name"><br>
<input type="date" name="birth" placeholder="birth"><br>
<button type="submit">更新</button><br>
</form>
<form action="player/3" method="post">
<input type="hidden" name="_method" value="DELETE"><br>
<button type="submit">删除</button><br>
</form>
<a href="player/1">查询单个</a><br>
<form action="player" method="post">
<input type="text" name="id" placeholder="id"><br>
<input type="text" name="name" placeholder="name"><br>
<input type="date" name="birth" placeholder="birth"><br>
<button type="submit">新增</button><br>
</form>
<form action="player" method="post">
<input type="hidden" name="_method" value="PUT"><br>
<input type="text" name="id" placeholder="id"><br>
<input type="text" name="name" placeholder="name"><br>
<input type="date" name="birth" placeholder="birth"><br>
<button type="submit">更新</button><br>
</form>
<form action="player/3" method="post">
<input type="hidden" name="_method" value="DELETE"><br>
<button type="submit">删除</button><br>
</form>
后端代码
@RestController
public class RestfulController {
@GetMapping("/player")
public List<Player> getAll() {
System.out.println("查询全部...");
return null;
}
@GetMapping("/player/{id}")
public Player getOne (@PathVariable("id") Integer id) {
System.out.println("查单个..."+id);
return null;
}
@PostMapping("/player")
public String add(Player player) {
System.out.println("新增...");
System.out.println(player);
return null;
}
@PutMapping("/player")
public String upDate(Player player) {
System.out.println("更新...");
System.out.println(player);
return null;
}
@DeleteMapping("/player/{id}")
public String delete(@PathVariable("id") Integer id) {
System.out.println("删除..."+id);
return null;
}
}
public class RestfulController {
@GetMapping("/player")
public List<Player> getAll() {
System.out.println("查询全部...");
return null;
}
@GetMapping("/player/{id}")
public Player getOne (@PathVariable("id") Integer id) {
System.out.println("查单个..."+id);
return null;
}
@PostMapping("/player")
public String add(Player player) {
System.out.println("新增...");
System.out.println(player);
return null;
}
@PutMapping("/player")
public String upDate(Player player) {
System.out.println("更新...");
System.out.println(player);
return null;
}
@DeleteMapping("/player/{id}")
public String delete(@PathVariable("id") Integer id) {
System.out.println("删除..."+id);
return null;
}
}
跨域问题
使用流程
在需要设置跨域请求的类上边加注释:
@CrossOrigin({"http://111.0.0.1:8848"})
@CrossOrigin({"http://111.0.0.1:8848"})
0 条评论
下一页