【SpringMVC】关于SpringMVC注解开发的一些杂记
文章目录
一、@RequestMapping注解类型
1、注解的使用
Spring 通过 @Controller 注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,这就需要使用 org.springframework.web.bind.annotation.RequestMapping 注解类型。RequestMapping 用于映射一个请求或一个方法,其注解形式为 @RequestMapping,可以使用该注解标注在一个方法或一个类上。
(1)标注在方法上
-
当标注在方法上时,该方法将成为一个请求处理方法,它会在程序接收到对应的URL请求时被调用。
例:
@RequestMapping(value = "/demo") public String demo() { System.out.println("hzz1服务器被访问……………………………………"); return "main"; }
-
上述代码中的demo方法就可以通过地址 http://localhost:8080/demo 进行访问。
(2)标注在类上
-
当标注在一个类上时,该类中的所有方法都将映射为相对于类级别的请求,请求控制器所处理的所有请求都被映射到value属性值所指定的路径下。
例:
@Controller @RequestMapping(value = "/hzz1") public class DemoAction { @RequestMapping("/demo") public String demo() { System.out.println("hzz1服务器被访问……………………………………"); return "main"; } }
-
由于在类上添加了 @RequestMapping 注解,并且其vlaue属性值为“/hzz1”, 因此上述代码方法的请求路径将变为 http://localhost:8080/hzz1/demo 。如果该类中还包含其他方法,那么在其他方法的请求路径中也需要加入"/hzz1"。
2、@RequestMapping注解的属性
属性名 | 类型 | 描述 |
---|---|---|
name | String | 可选,用于为映射地址指定的别名 |
vlaue | String[] | 可选,默认,用于映射一个请求和一种方法,可以标注在方法或类上 |
method | RequestMethod[] | 可选,指定该方法处理那种类型的请求,如GET、POST等 |
params | String[] | 可选,用于指定Request中必须包含某些参数的值,才可以通过其标注的方法处理 |
headers | String[] | 可选,用于指定Request中必须包含某些header的值,才可以通过其标注的方法处理 |
consumes | String[] | 可选,用于指定处理请求的提交内容类型(Context-Type),如 application/json、text/html等 |
produces | String[] | 可选,用于指定返回的内容类型,返回的内容类型必须是request请求头(Accept)中所包含的类型 |
二、五种数据提交的方式
注:前四种数据注入方式,会自动进行类型转换。但无法自动转换日期类型。
-
视图页面
<%-- Created by IntelliJ IDEA. User: 34162 Date: 2022/5/1 Time: 22:09 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> <form action="${pageContext.request.contextPath}/type.action" method="post"> <input type="submit" value="提交数据"> </form> <br><br> <h2>1、单个数据注入</h2> <form action="${pageContext.request.contextPath}/one.action"> <p> <label>姓名:</label> <input type="text" name="name"> </p> <p> <label>年龄:</label> <input type="text" name="age"> </p> <input type="submit" value="提交"> </form> <br><br> <h2>2、对象封装注入</h2> <form action="${pageContext.request.contextPath}/two.action"> <p> <label>姓名:</label> <input type="text" name="name"> </p> <p> <label>年龄:</label> <input type="text" name="age"> </p> <input type="submit" value="提交"> </form> <br><br> <h2>3、动态占位符提交</h2> <a href="${pageContext.request.contextPath}/three/张三/123.action">占位符提交(仅用于超链接)</a> <br><br> <h2>4、请求参数名称与形参不一致</h2> <form action="${pageContext.request.contextPath}/four.action" method="post"> <p> <label>姓名:</label> <input type="text" name="uName"> </p> <p> <label>年龄:</label> <input type="text" name="uAge"> </p> <input type="submit" value="提交"> </form> <br><br> <h2>5、使用HttpServletRequest对象提取</h2> <form action="${pageContext.request.contextPath}/five.action"> <p> <label>姓名:</label> <input type="text" name="uName"> </p> <p> <label>年龄:</label> <input type="text" name="uAge"> </p> <input type="submit" value="提交"> </form> </body> </html>
-
action代码
package com.Etui.controller; import com.Etui.entity.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; @Controller public class DataSubmit { @RequestMapping(value = "/type", method = RequestMethod.GET) public String dataSub1() { System.out.println("通过GET方法访问……………………"); return "main"; } @RequestMapping(value = "/type", method = RequestMethod.POST) public String dataSub2() { System.out.println("通过POST方法访问……………………"); return "main"; } @RequestMapping("/one") public String one(String name, Integer age) { System.out.println("username = " + name + ", age = " + (age + 10)); return "main"; } @RequestMapping("/two") public String two(User user) { System.out.println(user); return "main"; } // 若形参名称与地址中参数名相同,此处也可以不使用PathVariable注解 @RequestMapping("/three/{uName}/{uAge}") public String three( @PathVariable(value = "uName") String name, @PathVariable(value = "uAge") String age ) { System.out.println("username = " + name + ", age = " +age); return "main"; } /** 前端页面中提交的参数 * <p> * <label>姓名:</label> * <input type="text" name="uName"> * </p> * <p> * <label>年龄:</label> * <input type="text" name="uAge"> * </p> */ @RequestMapping("/four") public String four( @RequestParam(value = "uName") String name, @RequestParam(value = "uAge") Integer age ) { System.out.println("username = " + name + ", age = " + age); return "main"; } @RequestMapping("/five") public String five(HttpServletRequest request) { String name = request.getParameter("uName"); Integer age = Integer.parseInt(request.getParameter("uAge")); System.out.println("username = " + name + ", age = " + age); return "main"; } }
三、在POST形式表单提交中请求参数中文乱码问题
-
解决方案
在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。
-
在web.xml中添加如下过滤器即可
<!-- 创建过滤器,用于修改POST请求的默认编码格式 --> <filter> <filter-name>encodingType</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!-- private String encoding; private boolean forceRequestEncoding; private boolean forceResponseEncoding; --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingType</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
四、SpringMVC的四种跳转方式
默认的跳转是请求转发,直接跳转到jsp页面展示,还可以使用框架提供的关键字redirect:,进行一个重定向操作,包括重定向页面和重定向action,使用框架提供的关键字forward:,进行服务器内部转发操作,包括转发页面和转发action。当使用redirect:和forward:关键字时,视图解析器中前缀后缀的拼接就无效了。
-
前端测试代码
<%-- Created by IntelliJ IDEA. User: 34162 Date: 2022/5/2 Time: 21:18 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> <br><br> <a href="${pageContext.request.contextPath}/one.action">1、请求转发至页面(默认)</a> <br><br> <a href="${pageContext.request.contextPath}/two.action">2、请求转发至action</a> <br><br> <a href="${pageContext.request.contextPath}/three.action">3、重定向至页面</a> <br><br> <a href="${pageContext.request.contextPath}/four.action">4、重定向至action</a> </body> </html>
-
功能实现代码(action)
package com.Etui.controller; import com.Etui.entity.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; @Controller public class JumpAction { @RequestMapping("/one") public String one() { System.out.println("请求转发至页面……………………………………"); return "main"; } @RequestMapping("/two") public String two() { System.out.println("请求转发至action……………………………………"); return "forward:/other.action"; } @RequestMapping("/three") public String three() { System.out.println("重定向至页面……………………………………"); return "redirect:/admin/main.jsp"; } @RequestMapping("/four") public String four() { System.out.println("重定向至action……………………………………"); return "redirect:/other.action"; } @RequestMapping("/other") public String other() { System.out.println("other…………………………"); return "main"; } }
五、SpringMVC 支持的默认参数类型与返回类型
1、参数类型
-
HttpServletRequest
-
ServletResponse、HttpServletResponse
-
HttpSession
-
WebRequest、NativeWebRequest
-
java.uitl.Locale
-
java.uitl.TimeZone、java.time.ZoneId
-
java.io.InputStream、java.io.Reader、java.io.OutputSteam、java.io.Writer
-
org.springframework.http.HttpMethod
-
java.security.Principal
-
@PathVariable、@MatrixVariable、@RequestParam、@RequestHeader、@RequestBody、@RequestPart、@SessionAttribute、@RequestAttribute
-
java.uitl.Map、org.springframework.ui.Model、org.springframework.ui.ModelMap
-
RedirectAttributes
-
Errors、BindingResult
-
SessionStatus
-
UriComponentBuilder
-
常用的几个,示例:
@RequestMapping("/five") public String five( // 通常用作数据共享 HttpServletRequest request, HttpServletResponse response, Model model, ModelMap modelMap, Map map ) { User user = new User("甘雨", 19); request.setAttribute("servletRequest", user); model.addAttribute("model", user); modelMap.addAttribute("modelMap", user); map.put("map", user); return "main"; } /** <form action="${pageContext.request.contextPath}/four.action" method="post"> <p> <label>姓名:</label> <input type="text" name="uName"> </p> <p> <label>年龄:</label> <input type="text" name="uAge"> </p> <input type="submit" value="提交"> </form> */ @RequestMapping("/four") public String four( @RequestParam(value = "uName") String name, @RequestParam(value = "uAge") Integer age ) { System.out.println("username = " + name + ", age = " + age); return "main"; }
2、返回值类型
- ModelAndView
- Model
- Map
- View
- String
- void
- HttpEntiy<?> 或 ResponseEntity<?>
- Callable<?>
- DeferredResult<?>
六、关于日期处理
日期类型不能自动注入到方法的参数中。需要单独做转换处理。使用@DateTimeFormat注解,需要在springmvc.xml配置文件中添加<mvc:annotation-driven/> 标签。
1、在方法的参数中使用@DateTimeFormat注解
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
@RequestMapping("/myDate")
public String myDate(
@DateTimeFormat(pattern = "yyyy-mm-dd") Date myDate
) {
String formatTime = dateFormat.format(myDate);
System.out.println(formatTime);
return "show";
}
2、在类的成员setXXX()方法上使用@DateTimeFormat注解
@DateTimeFormat(pattern="yyyy-MM-dd")
public void setDate(Date date) {
this.date = date;
}
3、@InitBinder 注解解决类中日期问题
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
// 注册一个全局的日期处理注解
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-mm-dd"), true));
}
@RequestMapping("/myDate")
public String myDate(Date myDate) {
System.out.println(myDate);
System.out.println(simpleDateFormat.format(myDate));
return "show";
}
4、关于JSP页面的日期显示
注:日期在JSP页面进行格式化输出时,需要使用的国际化标签(JSTL)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>Show………………………………………………</h2>
<br><br><br>
<h2>学生表:</h2>
<table width="700px" border="1">
<tr>
<th>姓名</th>
<th>生日</th>
</tr>
<c:forEach items="${birthdays}" var="stu">
<tr>
<td>${stu.name}</td>
<!-- 通过 <fmt:formatDate>标签,格式化输出日期型数据 -->
<td>${stu.birthday} --=======-- <fmt:formatDate value="${stu.birthday}" pattern="yyyy年mm月dd日"></fmt:formatDate> </td>
</tr>
</c:forEach>
</table>
</body>
</html>
七、<mvc:annotation-driven> 标签的使用
- <mvc:annotation-driven> 会自动注册两个bean,分别为:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter,是springmvc为@controller分发请求所必须的。除了注册了这两个bean,还提供了很多支持。
- 1)支持使用ConversionService实例对表单参数进行类型转换;
- 2)支持使用@NumberFormat、@DateTimeFormat;
- 3)注解完成数据类型的格式化;
- 4)支持使用@RequestBody和@ResponseBody 注解;
- 5)静态资源的分流也是用该标签。
八、关于将资源防止在WEB-INF目录下
- 将动态资源放在WEB-INF目录下,可以保证资源的安全性。在WEB-INF目录下的动态资源不可以直接访问,必须要通过请求转发的方式进行访问。这样避免了通过地址栏直接对资源的访问。