1、项目结构
在正式介绍之前,首先看一下项目的整体结构,下文的所有内容都是在该结构的基础之上实现的。
首先解释一下每个文件夹的作用,如果你是用的是idea创建的springboot项目,会在项目创建的一开始resources文件夹下自动创建static以及templates文件夹。也就是说项目初始时有java、resource、static以及templates
这几个文件夹。一般static下存放js以及css样式文件,templates存放html页面。
以上是默认会创建的文件夹以及其作用
首先static文件夹以及templates文件夹是受保护的,也就是说相当于你将文件放到了传统的ssh或ssm项目的WEB-INF下了。所以也就是说这两个文件夹下的文件是无法通过url直接访问的,以至于在springmvc下使用会报404。
在讲重定向与转发之前先讲一下目录优先级的情况,webapp>META-INF/resources>resources>static>public
那么如何能够直接访问到html或者css呢?
方法一
我们可以在resources下创建一个名为public的文件夹,顾名思义,放在此文件夹下的文件是共有的,可以直接通过url访问,当然也可以springmvc重定向访问啦。
方法二
在main下创建webapp文件夹,如上图所示,将文件放到此文件夹下,效果同上。
注!文件夹名字是固定的,起别的名字还是会报404或者无效
首先呢public与webapp这二个在使用过程中一般创建一个目录就好了。
注意:这里我使用了thymeleaf模版,配置文件如下
server.port=80
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
这里的thymeleaf可以不写,其实都是默认的配置。
2、请求转发
SpringMVC
请求转发区别于重定向,请求转发地址栏不会发生改变、只发送一次请求、能携带原有的参数,但只可以在同一个服务器中进行转发。
注意:请求转发的转发内容可以是地址和页面,如果是页面则需要直接放到webapp目录或者public目录下。
2.1、传统Servlet的请求转发
@RequestMapping("/forwardCommon")
public void forwardCommon(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("c.html").forward(request,response);
}
这里的c.html是在webapp下的。
2.2、SpringMVC不经过视图解析器的请求转发
@RequestMapping("/forwardView1")
public String forwardViewOne(){
return "forward:/forwardCommon";
}
//这里转发的是地址
这里的请求转发的是上一个地址。
@RequestMapping("/forwardView2")
public ModelAndView forwardView(){
ModelAndView mv=new ModelAndView();
//这里不能直接访问WEB-INF下面的页面,例如不能写/WEB-INF/e.html
mv.setViewName("forward:f.html");
return mv;
}
这里访问的是f.html,该页面在public目录下
2.3、SpringMVC经过视图解析器的请求转发
@RequestMapping("/view1")
private String view1(String id) {
//这里可以直接写a,因为thymeleaf会自动拼接为a.html,并且到templates下面找
return "a"; // 和 return "/a" 一样,都会去templates下面找a.html。即是controller中存在/a的请求地址,也还是会去templates下面寻找a.html,而不是走对应的请求路径。
}
@RequestMapping("/view2")
private ModelAndView view2(ModelAndView model) {
ModelAndView mv=new ModelAndView();
mv.setViewName("b");//也是请求转发,会经过视图解析器
return mv;
}
这里是直接返回页面,可以携带数据,这两种方式是经常使用的,其实不经过视图解析起的路由也是请求转发。
即使是如下极端的情况:
@GetMapping("/index")
public String index(){
return "/index";
}
这种也是去templates中寻找index.html页面,而不是在controller中寻找/index请求的路径。
3、重定向(地址会变)
传统的重定向请求地址会改变(两次请求)、不能传递参数,但是利用SpringMVC
的重定向可以携带和传递参数。重定向相比于请求转发可以跨服,但是不能直接重定向访问WEB-INF
下的资源(可重定向后再进行一次请求转发)。
注意:重定向的内容可以是地址和页面,如果是页面则需要直接放到webapp目录或者public目录下。
3.1、传统Servlet重定向
@RequestMapping(value="/redirect",method = { RequestMethod.POST, RequestMethod.GET })
public void testRedirect(HttpServletResponse response) throws IOException {
response.sendRedirect("c.html"); //这里也可以重定向到一个controller中的请求地址,例如: "/a"
}
这里是访问直接放到webapp下的页面,也可以直接访问放到public下的页面
3.2、SpringMVC不带参数的重定向
第一种方式:
@RequestMapping(value="/redirect2",method = { RequestMethod.POST, RequestMethod.GET })
public String testRedirect2(){
return "redirect:/view1"; //这里/view1 或者是前面不加/,都会在controller中寻找地址,而不是去寻找html页面
}
这里是重定向到view1地址。
第二种方式:
@RequestMapping(value="/redirect3",method = { RequestMethod.POST, RequestMethod.GET })
public ModelAndView testRedirect3(){
ModelAndView mv=new ModelAndView();
mv.setViewName("redirect:/forwardView2");
return mv;
}
这里通过ModelAndView重定向
3.3、SpringMVC带参数的重定向
重定向的同时传递参数
第一种
redirectAttributes.addAttributie("prama",value);
这种方法相当于在重定向链接地址上追加传递的参数
@RequestMapping("/test1")
private String paraRed(RedirectAttributes ra) {
ra.addAttribute("id", 1);
return "redirect:/view1";
}
浏览器的地址栏会自动拼接成http://localhost/test1?id=1 ,注意这里我的端口号是80
第二种
redirectAttributes.addFlashAttributie("prama",value);
这种方法是隐藏了参数,链接地址上不直接暴露,用(@ModelAttribute(value = "prama")String prama)
的方式获取参数。
@RequestMapping("/test2")
private String paraRed2(RedirectAttributes ra) {
ra.addFlashAttribute("id", 1);
return "redirect:/view1";
}
这种方式浏览器不会自动拼接后面的字符串,重定向的地址也可以访问到对应的参数。
接收参数
在浏览器输入地址 http://localhost/test3?id=1
@RequestMapping("/test3")
private String paraRed3(@ModelAttribute("id") String id) {
System.out.println(id);//输出1
return "redirect:/view1";
}
这种方式也可以使用@PathVariable接收。
4、扩展
1.不使用thymeleaf模板引擎的时候
默认根路径为static
@RequestMapping("/loginSys1")
public String toHtml1(){
System.out.println("进入");
return "/login.html"; //找到resources下的static下的login.html
}
可以配置前后缀
spring:
mvc:
view:
prefix: / //这里如果不加/,那么返回的视图前就需要加上/
suffix: .html
@RequestMapping("/loginSys2")
public String toHtml2(){
System.out.println("进入");
return "login"; //找到resources下的static下的login.html
}
2.使用thymeleaf模板后
添加thymeleaf依赖后,默认根路径改为templates
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
@RequestMapping("/loginSys3")
public String toHtml3(){
System.out.println("进入");
return "user/login"; //找到resources下的templates下的user下的login.html
}
@RequestMapping("/loginSys4")
public String toHtml4(){
System.out.println("进入");
return "login"; //找到resources下的templates下的login.html
}
注意,thymeleaf默认配置:
spring.thymeleaf.cache=true //默认为true,开启devtools的时候要把缓存关闭,设置成false
spring.thymeleaf.prefix=classpath:/templates/ //默认springmvc会自动到templates目录下寻找
spring.thymeleaf.check-template-location=true
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
以上内容都是Thymeleaf默认配置好的,可以不用写。5、常用注解
@RequestParam,@PathVariable,
@RequestParam
和 @PathVariable
注解是用于从request中接收请求的,两个都可以接收参数,关键点不同的是@RequestParam
是从request里面拿取值,而 @PathVariable
是从一个URI模板里面来填充
例如:
@RequestMapping("/hello")
@ResponseBody
public String testRequest(@RequestParam(value = "param1") String param1){
System.out.println(param1);
return param1;
}
此时访问路径为 localhost/hello?param1=666 ,此时该方法会获取到请求路径中的参数,打印出666。
@RequestParam
支持下面四种参数
- 1.defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
- 2.name 绑定本次参数的名称,要跟URL上面的一样
- 3.required 这个参数是不是必须的
- 4.value 跟name一样的作用,是name属性的一个别名
@RequestMapping("/world/{id}")
@ResponseBody
public String testPath(@PathVariable(value = "id") String id){
System.out.println(id);
return id;
}
此时访问的路径为 localhost/world/123 ,此时该方法会把123认为就是路径中id的值,此时会打印出123。
全部评论