前言
大家好,我是Java码农ing
的作者,此篇文章或多或少可能有些瑕疵,欢迎大家明确指出我的缺点,为此感激不尽,我必有错改之无错加勉,我也同时能够希望和大家一起学习。如果觉得小编这篇文章写的不错的话,希望大家能够将这篇文章分享给周围的小伙伴们。好东西要一起分享。
SpringMvc
常用知识点梳理
1、@ResponseBody
作用:将handler
返回值转为Json
封装到响应体中。简言之,就是响应Json
数据
示例:
@RequestMapping("/path")
@ResponseBody
public Result responseToBody(){
return new Result(true,"");
}
相当于
// 创建一个Result对象
Result result = new Result(true,"");
// 创建Jackson核心对象
ObjectMapper mapper = new ObjectMapper();
// 将Java对象转换为Json字符串。
String jsonStr = mapper.writeValueAsString(result);
// 通过响应对象将Json字符串响应给客服端浏览器
response.getWriter().write(jsonStr);
2、@RestController
公式 :@RestController = @Controller + @ResponseBody
使用位置: 类上
使用场合 : 当控制器Controller
中所有的处理器handler
方法返回的都是json
时,用该注解
示例:
@RestController
public class XxxxController {
// ..... handle
}
3、@Controller
作用:标注在XxxxController
类上,表示将该类的实例交给Spring
容器来管理
示例:
@Controller
public class XxxxController {
//...
}
4、@RequestParam
作用: 接收请求参数
使用位置:形参前
该注解常用属性有三个,分别是required
、defaultValue
、value
,作用如下所示:
value
:指定请求参数名
required
:默认为true,表示该参数是必需的,false相反
defaultValue
: 指定默认值。通常用于分页查询。
举例:假设处理器形参为String username
,而请求参数中的参数名时name
,这时还想将name
参数名对应的参数值传递给处理器中的username
,就要使用到该注解。简言之,请求参数名和处理器方法形参名不一致时就采用该注解。
示例:
public void handleMethod(@RequestParam("name") String username){}
5、@PathVariable
作用:接收请求路径url
中的值
示例: 请求路径,如下所示:
htttp://localhost:8080/student/122
处理器代码,如下所示
@GetMapping("/student/{id}")
public 返回值 方法名(@PathVariable("id") Stirng id){
//...
}
6、@PostMapping
、@GetMapping
,@DeleteMapping
、@PutMapping
公式:
@PostMapping("/path")
= @RequestMapping(method=RequestMethod.POST,path="/path")
@PutMapping("/path")
= @RequestMapping(method=RequestMethod.PUT,path="/path")
@GetMapping("/path")
= @RequestMapping(method=RequestMethod.GET,path="/path")
@DeleteMapping("/path")
= @RequestMapping(method=RequestMethod.DELETE,path="/path")
作用:声明请求映射
示例:
增
@PostMapping
public 返回值 save(@ReqeustBody User user){}
改
@PutMapping
public 返回值 update(@RequestBody User user){}
查
@GetMapping("{id}")
public 返回值 find(@PathVariable("id") String id){}
删
@DeleteMapping("{id}")
public 返回值 delete(@PathVariable("id") String id){}
7、页面跳转4种方式
- 内部资源视图解析器 (核心类:
InternalResourceViewResolver
)+ 视图名称
<bean class="InternalResourceViewResolver内部资源视图解析器全限定名" id="唯一标识">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
bean>
@RequestMapping("/path")
public String jumpPage(){
// 请求转发
return "success";
}
- 关键字
forward
&redirect
重定向
@RequestMapping("/path")
public String jumpPage() {
return "redirect:/success.jsp";
}
请求转发
@RequestMapping("/path")
public String jumpPage(){
// 请求转发
return "forward:/success.jsp"
}
注意:使用关键字实现页面跳转,是不会走视图解析器的
回顾: 请求转发和重定向的区别?
- 使用
ModelAndView
示例:
ModelAndView
走视图解析器的情况
@RequestMappingO("/path")
public ModelAndView jumpPage(ModelAndView modelAndView) {
// 设置视图名称,比如:success
modelAndView.setViewName("success");
// 返回结果
return modelAndView;
}
ModelAndView
不走视图解析器的情况
@RequestMapping("/path")
public ModelAndView jumpPage(){
// 创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
// 设置视图名称
modelAndView.setViewName("forward:/success.jsp");
// 返回结果
return modelAndView;
}
想不到还可以这样setViewName("forward:/success.jsp")
使用吧?这也是我在无意间试出来的,想和大家一起分享
- 原生
Servlet Api
@RequestMapping("/path")
public void jumpPage(HttpServletReqeust request,HttpServletResponse response){
// 获取请求调度器,并实现请求转发
// request.getRequestDispatcher("/success.jsp").forward(request,response);
// 重定向
response.sendRedirect(request.getContextPath()+"/success.jsp");
}
8、配置前端控制器,核心类DispatcherServlet
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>DispatcherServlet全限定名servlet-class>
<init-param>
<param-name>param-name>
<param-value>classpath:SpringMvc核心配置文件.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
9、处理post
请求中文乱码问题,核心类CharacterEncodingFilter
web.xml
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>CharacterEncodingFilter全限定名filter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utt-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
10、释放静态资源
两种方式 1、 (
其次
)
<mvc:resources mapping="/**" location="/img/"/>
该标签有两个必需属性,给它就完事了。
2、 (
常用
)
<mvc:default-servlet-handler/>
注意:释放静态资源完后,可能会导致你的XxxxController
中定义的哪些处理器handler
方法无法访问,需要开启mvc
注解驱动,才会让你的哪些
@RequestMapping
、@PutMapping
等注解生效。
常规:通常释放静态资源后,都要将mvc
注解驱动开启
11、SpringMvc
入门案例
实现步骤:
0、导入核心依赖spring-web
、spring-webmvc
1、web.xml
中配置前端控制器
请参考8、配置前端控制器
2、创建SpringMvc
核心配置文件
命名规范:spring-mvc.xml
<context:componnent-scan base-package="xxx.xxx.controller"/>
3、创建控制器类,定义处理器方法。
@Controller // 将当前类实例交给Spring容器来管理
public class XxxxController{
// 定义处理器,完成跳转页面的功能
@RequstMapping("/jumpPage")
public String jumpPage(){
// 请求转发
return "/WEB-INF/success.jsp";
}
}
12、跨域访问
前提:只能在异步请求的情况下实现跨域访问。
什么是跨域访问?
答:当前页面所在的域与异步请求资源所在的域不一致。比如:百度访问京东服务器资源等现象。
什么是域?答:ip
地址、端口、域名、协议。只要其中有一个不同都会引发跨域访问。
示例:(协议+端口不一样)
- 当前页面
file:///D:/xxxx/xxx/xxx/send.html
- 异步请求
axios.get("http://localhost:8080/receive").then(response=>{
alert(response.data);
})
- 处理器方法
@ResponseBody
@RequestMapping("/receive")
public String receive(){
return "success";
}
从上面可以看出,当前页面所在的域和异步请求所在的域不同引发了跨域访问,但是浏览器默认是不支持跨域访问的,那怎么样才能够实现跨域访问呢?
答:在处理器方法上使用@CrossOrigin
注解即可。
13、配置Log4j
实现步骤:
1、导入log4j
坐标
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
2、编写log4j.properties
配置文件
3、配置log4j
<bean class="SqlSessionFactoryBean全限定名">
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
bean>
property>
bean>
14、设置共享数据的三种方式
Model
@RequestMapping("/shareData")
public String setShareData(Model model){
// 往request域中设置共享数据
model.addAttribute("key","value");
// 请求转发
return "success";
}
ModelAndView
@RequestMapping("/shareData")
public ModelAndView setShareData(ModelAndView modelAndView){
// 设置共享数据
modelAndView.addObject("key","value");
// 设置视图名称
modelAndView.setViewName("viewName");
// 返回结果
return modelAndView;
}
- 原生
Servlet api
@RequestMapping("/shareData")
public void setShareData(HttpServletRequest request,HttpServletResponse response,HttpSession session){
// 向session域中设置共享数据
//seesion.setAttribute("key","value");
// 重定向
//response.sendRedirect(request.getContextPath()+"/success.jsp");
// 向request域中设置共享数据
// 设置共享数据
reuqest.setAttribute("key","value");
// 获取请求调度对象并实现请求转发
response.getRequestDispatcher("/success.jsp").forward(request,response);
}
15、@RequestMapping
作用:声明/指定请求映射.
使用位置:类上、方法上
@RequestMapping
注解常用属性主要有两个,分别是:path
、method
path
:指定请求映射的路径
method
:指定该请求映射的请求方式。请求方式有多少种?参考HttpServlet
的源码
示例:
@ReqeustMapping("/path")
public void testRequestMapping(){
System.out.println("Hello , Java 码农ing");
}
下面是我对@RequestMapping
注解的个人看法:
其实我觉得@RequestMapping("/path")
,就相当于@WebServlet("/path")
这个注解。若不知道@WebServlet("/path")
这个注解的童鞋,请回顾一下配置Servlet
的方式。若你对@RequestMapping("/path")
该注解有更好的看法,请在下方留言。
16、@RequestBody
作用:接收请求体参数。只有post
请求才有请求体。
示例:
@RequestMapping("/jsonToObject")
public String jsonToObject(@RequestBody User user){
System.out.println(user);
return "./";
}
17、@DateTimeFormat
作用:接收指定日期格式的参数,默认格式为yyyy/MM/dd
。
使用位置: setter方法上、成员变量上、形参前
示例:
http://localhost:8080/toDate?date=2020-10-15
处理器代码如下:
@RequestMapping("/toDate")
public String toDate(@DateTimeFormat(pattern="yyyy-MM-dd") Date date){
System.out.println(date);
return "./";
}
18、@JsonFormater
作用:指定Json
转换格式。比如:日期转换。
使用场合:
假设请求体中Json
数据如下:
{
"username":"zhangsan",
"birthday":"2020/20/20",
"age":12
}
需求:要求将该数据转换为User
对象
User实体类,代码如下:
public class User {
private String username;
@JsonFormater(pattern="yyyy/MM/dd")
private Date birthday;
private Integer age;
}
注意:
Json
格式的默认日期转换格式为yyyy-MM-dd
处理器,代码如下:
@RequestMapping("/jsonToUser")
public String jsonToUser(@RequestBody User user){
// 输出User对象
System.out.println(user);
return "./";
}
19、文件上传
实现步骤:
1、导坐标commons-fileupload
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.1version>
dependency>
2、编写表单,必须
满足4个条件
- 文件域(
type=“file"
) - 文件域必须有
name
属性值 - 表单必须是
post
请求,因为Post请求数据长度无限制。 - 表单必须有
enctype="multipart/form-data"
示例:(以上传单个文件为例)
<form method="post" enctype="multipart/form-data" action="/upload/one">
<input type="file" name="file"/>
<button>上传button>
form>
3、配置文件上传解析器,核心类:CommonsMultipartResolver
示例:
<bean id="multipartResolver" class="CommonsMultipartResolver全限定名">
<property name="maxUploadSize" value="102400000000"/>
<property name="maxUploadSizePerFile" value="1024000000"/>
<property name="defaultEncoding" value="utf-8"/>
bean>
4、创建控制器类,定义处理器方法uploadFile
,完成文件上传
示例:
@Controller // 将当前类的实例交给Spring容器来管理
@RequestMapping("/upload") // 请求映射
public class UploadController {
@RequestMapping("/one") // 请求映射
public String uploadFile(HttpServletRequest request, MultipartFile file) throws IOException {
// 获取原始文件名称
String filename = file.getOriginalFilename();
// 获取资源文件在项目的真实路径
String realPath = request.getServletContext().getRealPath("/image");
// 封装成File对象
File dir = new File(realPath);
// 判断目录是否存在
if (!dir.exists()) {
dir.mkdirs(); // 创建文件夹
}
// 解决文件名问题(过长、后缀、重名)
String suffix = filename.substring(filename.lastIndexOf("."));
// 通过UUID工具生成新的文件名称
String newFileName = UUID.randomUUID().toString().replace("-", "") + suffix;
// 上传文件
file.transferTo(new File(dir,newFileName));
// 请求转发到上传成功的页面
return "/success.jsp";
}
}