mvc是啥,springMvc是啥,如何搭建springWeb项目,
在springMvc下的request和response怎么发请求,怎么进行响应?
springMvc处理文件相关:上传文件,uuid改名,静态资源映射,yaml配置路径,spring配置文件初步;
MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
Model:数据模型,JavaBean的类,用来进行数据封装。
View:指JSP、HTML用来展示数据给用户安卓-http,苹果,小程序
Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。
(1)继承一个父
org.springframework.boot spring-boot-starter-parent 2.3.0.RELEASE
(2)web项目的包+前端模板引擎
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf
(3)完整的pom.xml文件
4.0.0 com.tianju springMvc620 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.3.0.RELEASE 8 8 UTF-8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok com.alibaba fastjson 2.0.22
要点:
Main.java文件
package com.tianju; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; /** * springMvc的主启动类 * 1.本质是配置类;@SpringBootApplication :@Configuration是它的爷爷辈 * 2.启动容器,SpringApplication.run(Main.class); */ @SpringBootApplication public class Main { public static void main(String[] args) { // 集成了的new对象,放容器,启动执行 ApplicationContext ac = SpringApplication.run(Main.class); } }
要点:
server: port: 80
要点:
ResponseControllerDemo.java文件
package com.tianju.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { @RequestMapping({"/hello","/hello2"}) // 二级目录 @ResponseBody public String hello(){ return "Hello SpringMvc"; } }
@PostMapping,@GetMapping,@DeleteMapping,@PutMapping
@RequestMapping
@PostMapping(“/hello”)
@GetMapping
@DeleteMapping
@PutMapping
要点:
http://localhost/demo/hello?username=&age=
package com.tianju.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { @RequestMapping("/hello") // 二级目录 @ResponseBody public String hello(String username,Integer age){ System.out.println(username); System.out.println(age); return "Hello SpringMvc"; } }
要点:
默认必须传值,不传会报400异常;
如果不想传,就加required=false;
还可以给个默认值,defaultValue=“admin”;【应用:分页的时候,默认第一页,默认每页10条数据】
http://localhost/demo/hello?name=hell
@RequestMapping("/hello") // 二级目录 @ResponseBody public String hello(@RequestParam(value = "name") String username){ System.out.println(username); return "Hello SpringMvc"; }
package com.tianju.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { @RequestMapping("/hello") // 二级目录 @ResponseBody public String hello(@RequestParam(value = "pageNum",defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize){ System.out.println(pageNum); System.out.println(pageSize); return "Hello SpringMvc"; } }
要点:
http://localhost/demo/search/mobilephone/red
package com.tianju.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.security.SignedObject; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { // http://localhost/demo/search/mobilephone/red @RequestMapping("/search/{item}/{color}") // 二级目录 @ResponseBody public String hello(@PathVariable("item") String item, @PathVariable("color") String color){ System.out.println(item); System.out.println(color); return "Hello SpringMvc"; } }
要点:
http://localhost/demo/add/user?username=peter&password=123&hobby=learn&hobby=game
package com.tianju.controller; import com.tianju.entity.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.security.SignedObject; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { // http://localhost/demo/add/user?username=peter // &password=123&hobby=learn&hobby=game @RequestMapping("/add/user") // 二级目录 @ResponseBody public String hello(User user){ System.out.println(user); return "Hello SpringMvc"; } }
要点:
http://localhost/demo/date?birthday=2021/05/28
package com.tianju.controller; import com.tianju.entity.User; import lombok.Data; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.security.SignedObject; import java.util.Date; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { // http://localhost/demo/date?birthday=2021/05/28 @RequestMapping("/date") // 二级目录 @ResponseBody public String hello(Date birthday){ System.out.println(birthday); return "Hello SpringMvc"; } }
Failed to convert from type [java.lang.String] to type [java.util.Date] for value ‘2021-5-28’; nested exception is java.lang.IllegalArgumentException]
要点:
需要啥写啥;
HttpServletRequest request,
HttpSession httpSession,
http://localhost/demo/set/session http://localhost/demo/native
package com.tianju.controller; import com.tianju.entity.User; import lombok.Data; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.security.SignedObject; import java.util.Date; /** * controller层, * 1.在容器中: @Controller * 2.用来处理网络请求:即 @RequestMapping("/demo") * 既可以放在类上:一级目录; * 也可以在方法上:二级目录:http://localhost/demo/hello */ @Controller @RequestMapping("/demo") // 一级目录 public class ResponseControllerDemo { // http://localhost/demo/date?birthday=2021/05/28 @RequestMapping("/native") // 二级目录 @ResponseBody public String hello(HttpServletRequest request, HttpSession httpSession, HttpServletResponse response, @RequestHeader("Connection") String connection, @CookieValue("JSESSIONID") String jsessionid){ // 1.request里面就可以获得session,之前servlet就是这样的 HttpSession session = request.getSession(); // 2.加上httpSession,也能获得; Object username = httpSession.getAttribute("username"); System.out.println(username); System.out.println(response); System.out.println("----获取请求头里的connection------"); System.out.println(connection); System.out.println(jsessionid); return "Hello SpringMvc"; } @RequestMapping("/set/session") @ResponseBody public String setSession(HttpSession session){ session.setAttribute("username", "peter"); System.out.println(session); return "success"; } }
请求头
获取connection和 jsessionid
需要一个包,前端模板引擎,类似于jsp
org.springframework.boot spring-boot-starter-thymeleaf
要点:
响应是json,要加@ResponseBody;
时间显示的问题,要GMT+8:
@JsonFormat(pattern = “yyyy-MM-DD hh:mm:ss”, timezone = “GMT+8”)
如果一个controller响应都是json则,可以用@RestController代替 @Controller 和 @ResponseBody
注意这里,日期转换格式写错了,DD要改成小写dd
日期格式的转换
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",timezone = "GMT+8") private Date birthday;
controller的代码
package com.tianju.controller; import com.tianju.entity.ResData; import com.tianju.entity.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; import java.util.Date; /** * 响应相关:1.响应json;2.响应页面 * 要点: * 1.在容器@Controller; * 2.路径;@RequestMapping("/resp"); * 3.如果是响应json,需要加@ResponseBody; * 4.如果响应页面,则返回值是string * 补充:如果一个controller响应都是json * 则,@RestController代替 @Controller 和 @ResponseBody */ @Controller @RequestMapping("/resp") //@RestController // 等价于@Controller + @ResponseBody public class ResponseControllerDemo { @RequestMapping("/json") @ResponseBody // 如果响应是json,必须加 public ResData respJson(){ User user = new User("peter", "123", new Date(), Arrays.asList(new String[]{"learn","movie"})); return new ResData(200, "success", user); } }
可以不写responseBody,用@RestController
要点:
服务器响应html代码,显示在前端页面上
访问resources下的文件可以修改,不建议
访问连接
http://localhost/resp/list
后端代码
/** * 响应一个页面 * @return list页面,会在前面拼 /templates,后面拼.html * 最终访问到xxx/templates/opus/list.html */ @RequestMapping("/list") public String respHtml(){ return "/opus/list"; }
要点:
// 1.定义要跳转的页面,2.添加要共享的数据 ModelAndView mv = new ModelAndView("opus/list"); mv.addObject("username", "peter");
第一种方式:不建议
第二种方式:以后共享数据都用这种方式
共享值显示到前端
@RequestMapping("/listAndData") public ModelAndView respHtmlData(){ // 1.定义要跳转的页面,2.添加要共享的数据 ModelAndView mv = new ModelAndView("opus/list"); mv.addObject("username", "peter"); return mv; }
要点:没有返回值,用void
package com.tianju.controller; import com.alibaba.fastjson.JSON; import com.tianju.entity.ResData; import com.tianju.entity.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Date; /** * 响应相关:1.响应json;2.响应页面 * 要点: * 1.在容器@Controller; * 2.路径;@RequestMapping("/resp"); * 3.如果是响应json,需要加@ResponseBody; * 4.如果响应页面,则返回值是string * 补充:如果一个controller响应都是json * 则,@RestController代替 @Controller 和 @ResponseBody */ @Controller @RequestMapping("/resp") //@RestController // 等价于@Controller + @ResponseBody public class ResponseControllerDemo { @RequestMapping("/json") @ResponseBody // 如果响应是json,必须加 public ResData respJson(){ User user = new User("peter", "123", new Date(), Arrays.asList(new String[]{"learn","movie"})); return new ResData(200, "success", user); } /** * 响应一个页面 * @return list页面,会在前面拼 /templates,后面拼.html * 最终访问到xxx/templates/opus/list.html */ @RequestMapping("/list") public String respHtml(){ return "/opus/list"; } @RequestMapping("/listAndData") public ModelAndView respHtmlData(){ // 1.定义要跳转的页面,2.添加要共享的数据 ModelAndView mv = new ModelAndView("opus/list"); mv.addObject("username", "peter"); return mv; } /** * 如果想自己处理,就用void */ @RequestMapping("/self") public void test(HttpServletResponse response) throws IOException { ResData resData = new ResData(200, "success", null); response.getWriter().write(JSON.toJSONString(resData)); } }
要点:
可以拿到图片,获取图片大小,进行大小处理
后端controlle代码
package com.tianju.controller; import com.tianju.entity.ResData; import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; /** * 上传文件: * 要点: * 1.前端怎么提交: * 2.后端怎么接收: * 3.接收后怎么处理: */ //@RestController // 等价于@Controller 和 @ResponseBody @Controller @RequestMapping("/file") public class UploadController { // 1.先到上传图片的页面 @RequestMapping("/uploadPage") public String uploadPage(){ return "/opus/upload"; } // 2.处理前端上传的图片 @RequestMapping("/upload") @ResponseBody public ResData uploadImg(MultipartFile headImg) throws IOException { long size = headImg.getSize(); // 文件大小 String filename = headImg.getOriginalFilename(); // 文件名 System.out.println("上传的文件:"+filename+",文件大小"+size); // 对文件进行处理 // (1)拿到输入流,然后保存到本地;以后也可能通过网络发送到其他地方 InputStream inputStream = headImg.getInputStream(); FileOutputStream outputStream = new FileOutputStream("D:/06/" + filename); IOUtils.copy(inputStream, outputStream); // 谁建的谁关 outputStream.close(); // (2)不用流直接存到本地文件中 headImg.transferTo(new File("D:\\620\\"+filename)); return new ResData(200, "ok", null); } }
前端upload.html页面代码
Title
要点:
package com.tianju.controller; import com.tianju.entity.ResData; import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.UUID; /** * 上传文件: * 要点: * 1.前端怎么提交: * 2.后端怎么接收: * 3.接收后怎么处理: */ //@RestController // 等价于@Controller 和 @ResponseBody @Controller @RequestMapping("/file") public class UploadController { // 1.先到上传图片的页面 @RequestMapping("/uploadPage") public String uploadPage(){ return "/opus/upload"; } // 2.处理前端上传的图片 @RequestMapping("/upload") @ResponseBody public ResData uploadImg(MultipartFile headImg) throws IOException { long size = headImg.getSize(); // 文件大小 String originalFilename = headImg.getOriginalFilename(); // 文件名 System.out.println("上传的文件:"+originalFilename+",文件大小"+size); // 对文件进行处理 (2)不用流直接存到本地文件中 // 获得uuid,并把中间-去掉 String randomStr = UUID.randomUUID().toString().replace("-", ""); // 获取上传文件的后缀 int i = originalFilename.lastIndexOf("."); String suffix = originalFilename.substring(i, originalFilename.length()); headImg.transferTo(new File("D:\\620\\"+randomStr+suffix)); return new ResData(200, "ok", null); } }
要点:
本地文件协议,/** 表示子目录也可以找到
网页访问本地图片
springMvcConfig.java文件
package com.tianju.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * springMvc的配置类,spring的相关配置都在这里 * 要点: * 1.是配置类;@Configuration * 2.是springMvc的配置类:implements WebMvcConfigurer */ @Configuration public class SpringMvcConfig implements WebMvcConfigurer { /** * 能够把服务器上的一个目录,映射成一个路径,http可以直接访问到 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 在浏览器上,如果访问/bookImg/1.jpg,springMvc就去D:\620\1.jpg找对应的文件 // /bookimg/** 表示子目录下的文件也能找到 registry.addResourceHandler("/bookimg/**") .addResourceLocations("file:D:\\620\\"); } }
要点:
application.yml文件
server: port: 80 ## 图片上传的路径 imgLocation: D:\620\
其他文件获取:
package com.tianju.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * springMvc的配置类,spring的相关配置都在这里 * 要点: * 1.是配置类;@Configuration * 2.是springMvc的配置类:implements WebMvcConfigurer */ @Configuration public class SpringMvcConfig implements WebMvcConfigurer { @Value("${imgLocation}") private String imgLocation; /** * 能够把服务器上的一个目录,映射成一个路径,http可以直接访问到 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 在浏览器上,如果访问/bookImg/1.jpg,springMvc就去D:\620\1.jpg找对应的文件 // /bookimg/** 表示子目录下的文件也能找到 registry.addResourceHandler("/bookimg/**") .addResourceLocations("file:"+imgLocation); } }
1.Model View Controller 模型视图控制器;
2.idea建springWeb项目,普通项目,继承一个父,主启动类@SpringBootApplication,application.yml配置文件;
3.浏览器请求@RequestMapping(“/demo”),可以在类上,方法上,一二级目录;
4.请求传参@RequestParam(value = “pageNum”,defaultValue = “1”),可以用在分页上;
5.请求:查询xxx/search/手机/白色,@RequestMapping(“/search/{item}/{color}”)----@PathVariable(“item”);
6.请求:获取request,参数加上HttpServletRequest request;
7.服务器响应,响应页面,响应json,自己处理;
8.响应JSON,@ResponseBody,时间格式,@JsonFormat(pattern = “yyyy-MM-DD hh:mm:ss”, timezone = “GMT+8”);
9.响应页面:返回值为string,不能加@ResponseBody;
10.响应页面带点数据:ModelAndView 且共享数据[[${usename}]];
11.上传文件MultipartFile接收,分段post提交:enctype=“multipart/form-data”;
12.静态资源映射:springMvcConfig 配置类@Configuration,实现接口WebMvcConfigurer,addResourceHandlers方法,本地文件协议file:/ ;
13.拿到application.yml文件中的值,用@Value(" $ {imgLocation}" ;