当前位置:   article > 正文

java spring mvc介绍_SpringMVC介绍

mvc的model的addatttibute

什么是MVC

06c4e0946fa8dee2d987fb0e8e0f8dce.png

2491ae04311cde6488fc78c3cdf46cd1.png

最典型的MVC就是JSP+servlet+JavaBean的模式

00e068a1486a706f77945334856adff4.png

Spring-web

cb99fff59a9860555cc554354d770d70.png

SpringMVC

89f4908504d2f28b9141214f825662b9.png

03930ababbc84921871aa7e757b3f97b.png

public class MyServlet extendsHttpServlet{

@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException{

String username= req.getParameter("username");

req.getSession().setAttribute("username", username);

req.getRequestDispatcher("index.jsp").forward(req, resp);

}

@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException{this.doPost(req. resp);

}

}

web.xml配置servlet

1368f2472e72aee0717da78e8c7bf876.png

e8d2018eeda1f72baf6fb9f049663a84.png

springmvc.xml

5a5d67c6b52b964380af4af162272a45.png

idea,添加lib文件夹

86926ae4e54b98a654f6fb48304d9c1d.png

e9a11b1469a2411f33dd6d14a41f856e.png

public classHelloController{public voidhello(){

System.out.println(this.getClass().getName());

}public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throwsException{//创建对象

ModelAndView mv = newModelAndView();//添加视图名称, 要跳转的页面名称

mv.setViewName("hello");//向前端页面添加属性值

mv.addObject("hello", "hello, springmvc");return null;

}

}

Spring的处理过程

59d8e931b38b2861d62c30ca13c61cb8.png

534883b580a3f581896a0878723d4d24.png

@Controllerpublic classHelloController{

@RequestMapping("/hello")publicString hello(){

map.put("hello", "hello,SpringMVC");return "hello";

}

@RequestMapping("/hello")public String hello2(Mapmap){

map.put("hello", "hello, SpringMVC");return "hello";

}

@RequestMapping(value= "/hello", method =RequestMethod.POST)public String hello2(Mapmap){

map.put("hello", "hello, SpringMVC");return "hello";

}

@RequestMapping(value= "/hello", param = {"username"})public String hello2(Mapmap){

map.put("hello", "hello, SpringMVC");return "hello";

}

@RequestMapping(value= "/hello", param = {"username=zs", "age"})public String hello2(Mapmap){

map.put("hello", "hello, SpringMVC");return "hello";

}//headers 表示限制请求头中的相关属性值, 用来做请求的限制

@RequestMapping(value = "/hello", headers = {"User-Agent=..."})public String hello2(Mapmap){

map.put("hello", "hello, SpringMVC");return "hello";

}//produces: 限制请求中的Content-Type//consumers: 限制响应中的Content-Type//@RequestMapping可以进行模糊匹配//?: 替代任意一个人字符//*: 提供多个字符//**: 替代多层路径

}

常用的注解

参数列表

@Controllerpublic classPathVariableController{

@RequestMapping("/testPathVariable/{name}")public String testPathVariable(@PathVariable String name){//rest方式用的比较多

request.getParameter("name");

System.out.println(name);return "hello";

}

}

@Controllerpublic classPathVariableController{

@RequestMapping("/testPathVariable/{id}")public String testPathVariable(@PathVariable("id") String name){//rest方式用的比较多

request.getParameter("name");

System.out.println(name);return "hello";

}

}

@Controllerpublic classPathVariableController{

@RequestMapping("/testPathVariable/{id}")public String testPathVariable(@PathVariable("id") Integer id, @PathVariable("name") String name){//rest方式用的比较多

request.getParameter("name");

System.out.println(name);return "hello";

}

}

web.xml

bdef6ca331fcb041d0b3fd540baa928e.png

springmvc.xml

2d1654c9b4a536c095649086fdcf9211.png

如果不使用rest,那么增删改查就需要建立四个接口,如果用rest那么用GET,POST,PUT,DELETE四个提交方式对应增删改查

public classUserDao{public voidsave(User user){

System.out.println("save");

}public voidupdate(Integer id){

System.out.println("update");

}public voiddelete(Integer id){

System.out.println("delete");

}public voidquery(){

System.out.println("query");

}

}public classUser{

}

@Controllerpublic classUserController{

@AutowiredprivateUser userDao;

@RequestMapping("/save")publicString save(){

userDao.save(newUser());return "success";

}

@RequestMapping("/update")publicString update(Integer id){

userDao.update(id);return "success";

}

@RequestMapping("/delete")publicString delete(Integer id){

userDao.delete(id);return "success";

}

@RequestMapping("/query")publicString query(){

userDao.query();return "success";

}

}

REST

55b1380b8089d793f997dcb593d31f88.png

POST:创建              /user/1

GET:获取                /user

PUT:更新资源          /user/1

DELETE:删除资源   /user/1

导包

f5cca9ed05bf1cda2037aa5930e99392.png

web.xml

c7435de4008b6eb86bd4ca72d0f1e85f.png

7e17140bbf8fce2986cc7ebfd8790496.png

public classUserDao{public voidsave(User user){

System.out.println("save");

}public voidupdate(Integer id){

System.out.println("update");

}public voiddelete(Integer id){

System.out.println("delete");

}public voidquery(){

System.out.println("query");

}

}public classUser{

}

@Controllerpublic classUserController{

@AutowiredprivateUser userDao;

@RequestMapping(value= "/user", method =RequestMethod.POST)publicString save(){

userDao.save(newUser());return "success";

}

@RequestMapping(value= "/user", method =RequestMethod.PUT)publicString update(Integer id){

userDao.update(id);return "success";

}

@RequestMapping(value= "/user", method =RequestMethod.DELETE)publicString delete(Integer id){

userDao.delete(id);return "success";

}

@RequestMapping(value= "/user", method =RequestMethod.GET)publicString query(){

userDao.query();return "success";

}

}public class MyFilter implementsFilter{public voiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){

filterChain.doFilter(servletRequest, servletResponse);

servletRequest.setCharacterEncoding("UTF-8");

servletResponse.setCharacterEncoding("UTF-8");

}

}

4657cc8b3b9310f46d9dda48f0ed6ba4.png

SpringMVC的使用

7217341ec097892126b3725f6bb14010.png

RequestParam和PathVariable不要混淆

RequestParam获取的是问号后面的键值对

PathVariable获取的是路径后面的值

RequestParam的参数

value:获取的参数值

required:表示当前属性值是否存在,默认值是true,如果没有,400,bad request

defaultValue:如果有传递参数就是用传递进来的参数,如果没有就是用默认值

乱码问题解决

需要设置过滤request和response的编码方式,可以自己手动编写过滤器,也可以由现成的框架实现

post:分别设置request和response编码格式

get:在tomcat的server.xml文件中,添加URIEncoding=utf-8

调整顺序可以解决乱码问题

77d0d63210a7a837083bdff7ba475af3.png

在一个应用程序中,可能包含n多个过滤器,一般没有顺序要求,如果设置了编码过滤器,必须要将编码过滤器设置到最上面,保证编码过滤器,优先执行

编码过滤器,要放在最上面的位置

cd895e719c032443efcd0b66657b6470.png

@Controllerpublic classRequestController{

@RequestMapping("/testRequest")public String testRequest(@RequestParam(value = "username", required = false) String name){

System.out.println(name);return "success";

}

}//获取请求头信息

@Controllerpublic classRequestController{

@RequestMapping("/testRequest")publicString testRequestHeader(@testRequestHeader String userAgent){

System.out.println(userAgent);return "success";

}//request.getCookie()

@RequestMapping("/testCookie")public String testCookie(@CookieValue("JSESSIONID"), String jsid){

System.out.println(jsid);return "success";

}

}

@Controllerpublic classUserController22{

@RequestMapping("/testUser")publicString testUser(User user){

System.out.println(user);return "success";

}

}

每次tomcat可以启动,可以自己启动

131a3422721ac73ce29aca070e9a3b90.png

SessionAttribute

@Controller

@SessionAttributes(value= {"username", "msg"}, types = Integer.class) //每次向request设置作品用于的时候, 顺带向session中保存一份

public classOutputController{

@RequestMapping("/output")public String output(Mapmap){

map.put("msg", "hello,output");

System.out.println(model.getClass());return "success";

}

@RequestMapping("/output1")public String output(Mapmap){

map.put("msg", "hello,output1");return "success";

}

@RequestMapping("/output2")public String output(Mapmap){

model.addAttribute("msg", "hello, output2");return "success";

}

@RequestMapping("/output3")public String output(Mapmap){

map.put("msg", "hello,output3");return "success";

}

@RequestMapping("/output4")public ModelAndView output(Mapmap){

ModelAndView mv= newModelAndView();

mv.setViewName("success");

mv.addObject("msg", "output4");returnmv;

}

@RequestMapping("/testSession")publicString testSession(Model model){

model.addAtttibute("username", "zs");return "success";

}

}

被@ModelAttribute注释的方法会在此controller每个方法执行前被执行,因此对于一个controller映射多个URL的用法来说,要谨慎使用

@Controllerpublic classUserController{

Object o1= null;

Object o2= null;

Model m1= null;

@RequestMapping("update")public String update(@ModelAttribute("user2") User user, Model model){

o2=user;

System.out.prinltn(user);

System.out.println(o1 == o2);//true 指向同一个对象

System.out.println(m1 == model);//false

return "success";

}

@ModelAttributepublic voidtestModelAttribute(Model model){

User user= newUser();

user.setId(1);

user.setName("name");

user.setPassword("1234");

model.addAttribute("user2", user);

o1=user;

m1=model1;

}

}

SessionAttributes要注意,在使用的时候如果没有对应的值

f6291ef03c53ab00c25f07635e18c44c.png

@Controllerpublic classUserController{

Object o1= null;

Object o2= null;

Model m1= null;

@RequestMapping("update")public String update(@ModelAttribute("user2") User user, Model model){

o2=user;

System.out.prinltn(user);

System.out.println(o1== o2);//true 指向同一个对象

System.out.println(m1 == model);//false

return "success";

}//加一个user2标识, 可以匹配到user2

@ModelAttribute("user2")public voidtestModelAttribute(Model model){

User user= newUser();

user.setId(1);

user.setName("name");

user.setPassword("1234");

model.addAttribute("user2", user);

o1=user;

m1=model1;

}

}

forward转发

在使用转发的时候,要添加forward: 前缀

可以实现多次转发请求,可以回到页面,也可以转发到其他页面请求中

@Controllerpublic classForWardController{

@RequestMapping("/forward")publicString forward(){

System.out.printfln("forward");return "forward:/index.jsp";

}

@RequestMapping("/forward2")publicString forward2(){

System.out.printfln("forward2");return "forward:/forward";

}

}

redirct重定向

重定向操作也不会经过视图处理器

@Controllerpublic classRedirctontroller{

@RequestMapping("/redirect")publicString forward(){

System.out.printfln("forward");return "redirect:/index.jsp";

}

@RequestMapping("/redirect2")publicString forward2(){

System.out.printfln("redirect2");return "redirect:/redirect";

}

}

转发与重定向的区别

转发是服务端

重定向是客户端

60dedf735a86660538d97d79b1dacbf1.png

f7d1a0324066348d8d16e8923bab6b22.png

springmvc.xml

默认的servlet处理类

af1df5c34f8e798162c8a255c22902f9.png

保证动态请求和静态资源能够访问

3cebf294b7703fb95e14ada360565b6e.png

自定义视图解析器

InternalResourceViewResolver

public class MyViewResolver implementsViewResolver, Ordered{private int order = 0;

@Overridepublic View resolveViewName(String viewName, Locale locale) throwsException{if(viewName.startsWith("test")){

System.out.println(viewName);returnMyView();

}else{return null;

}

}

}public void setOrder(intorder){this.order =order;

}

@Overridepublic intgetOrder(){return 0;

}public class MyView implementsView{

@OverridepublicString getContentType(){return null;

}

@Overridepublic void render(Map model, HttpServletRequest request, HttpServletResponse response) throwsException{

System.out.println("model:" +model);

PrintWriter writer=response.getWriter();

writer.write("test");

writer.write("gogogo");

}

}

@Controllerpublic classViewResolverController{

@RequestMapping("/test")publicString testView1(){

System.out.println("testView");return "test:/index";

}

@RequestMapping("/test2")publicString testView2(){

System.out.println("testView");return "test2:/index";

}

}

springmvc.xml

1a5873a1a9a1fd9364fd3b2dfc42586f.png

value的值越大,优先级越小

添加自定义的类型转换器到ConversionServiceFactoryBean中

eea5c44586042b2f98882247836b1326.png

@Componentpublic class MyConverter implements Converter{

@OverridepublicObject convert(Object source){

User user= null;if(source != null && "".equals(source) && (source.split("-").length == 4)){

user= newUser();

user.setId(Integer.parseInt(source.split("-")[0]));

user.setName(source.split("-")[1]);

user.setAge(Integer.parseInt(source.split("-")[2]));

user.setPassword(source.split("-")[3]);

}return null;

}

}//自定义类型转换器的时候, 注意对应的属性值跟方法中参数值对应起来

@Controllerpublic classMyConverterController{

@RequestMapping("/converter")publicString testConverter(User user, Model model){

System.out.println(user);

model.addAttribute("user", user);return "success";

}

}

自定义日期转换器

springmvc.xml

4dfd29330fa43de500c4f091fb42ebbc.png

如果需要添加日期格式化器,只需要在实体类上添加@DataTimeFormat("格式")即可

如果配置日期格式化器的时候,同时配置了类型转换器,那么就会失效

需要使用 FormattingConversionServiceFactoryBean 对象

//如果使用默认的类型转换器, 那么在输入日期的时候使用/作为分隔

@Controllerpublic classDateConverterController{

@RequestMapping("/testDateConverter")publicString testDateConverter(User user){

System.out.println(user);return "success";

}

}public classUser{

@DateTimeFormat(pattern= "yyyy-MM-dd")privateDate birth;

}

数据校验

JSR303提供的标准校验

fa93b988af86ae067d138abbe1bb5973.png

Hibernate Validator 扩展注解

c23d931beacbb603373b606d6d694ac8.png

JSR校验框架

ee0622d37484b4a3056de684151f6e45.png

导包

b0a2637d0a1a59bbc376369663f88c9f.png

日期格式化器

public classPerson{

@NouNullprivateInteger id;

@Length(min= 3, max = 10)privateString name;privateInteger age;privateString gender;

@Past//设置的日期只能是之前的日期

privateDate birth;

@EmailprivateString gmail;

}

@Controllerpublic classValidationController{

@RequestMapping("/validation")publicString validate(@Valid Person person, BindingResult){if(BindingResult.hasErrors()){

System.out.println("验证失败");//获取到当前所有的错误

List fieldErrors =bindingResult.getFieldErrors();for(FieldError fieldError : fieldErrors){

System.out.println(fieldError.getField());

System.out.println(fieldError.getDefaultMessage());

map.put(fieldError.getField(), fieldError.getDefaultMessage());

}

model.addAttribute("errors", map);return "forward:/login.jsp";

}else{

System.out.println("登陆成功");return "success";

}

}

}

springmvc_json

ab3d5003c71a7d85d1fa05cb4e88b910.png

@RequestBody 表示把当前请求的内容

@ResponseBody 解析字符串为标签

@Controllerpublic classJsonController{

@ResponseBody

@RequestMapping("/json")publicString json(){

List list = new ArrayList();

list.add(new User("test1", 12, "man"));

list.add(new User("test2", 13, "woman"));

list.add(new User("test3", 14, "man"));returnlist;

}

@ResponseBody//该注解会解析字符串为标签

@RequestMapping("/json2")publicString json2(){return "

test

";

}

@RequestMapping("/testRequestBody")publicString testRequestBody(@RequestBody String body){

System.out.println(body);return "success";

}

@RequestMapping("/testRequestJson")publicString testRequestJson(@RequestBody User user){

System.out.println(user);return "success";

}

}public classUser{privateInteger id;privateString name;privateInteger age;privateString gender;publicUser(){

}publicUser(String name, Integer age, String gender){

}

}

自定义响应ResponseEntity

@Controllerpublic classEntity{

@RequestMapping("test")public String test(HttpEntityhttpEntity){

System.out.println(httpEntity);

String body=httpEntity.getBody();return "success";

}//自定义响应相关的信息, 包含body和header

@RequestMapping("testResponseEntity")publicString teestResponseEntity(){

String body= "

gogogo

";

MultiValueMap header = newHttpHeaders();

header.add("set-cookie", "name=zs");return new ResponseEntity(body, header, HttpStatus.OK);

}

}

servlet下载文件

@Controllerpublic classDownController{

@RequestMapping("/download")publicString download(HttpServletRequest request){//获取下载路径

ServletContext servletContext =request.getServletContext();

servletContext.getRealPath("/scripts/...");//通过io流对文件读写

FileInputStream FileInputStream = newFileInputStream(realPath);byte[] bytes = new byte[FileInputStream.available()];

FileInputStream.read(bytes);

FileInputStream.close();

HttpHeaders httpHeaders= newHttpHeaders();

httpHeaders.set("Content-Disposition", "attachment:filename=...");return new ResponseEntity(bytes, httpHeaders, HttpStatus.OK);

}

}

servlet上传文件

cb87b95883cca21bdb539db0381dc764.png

springmvc.xml

d9bacbc35457ac0fbb2d967606e52f00.png

添加jar包

d96529ed2a7500246dbff92e52bd6b74.png

多文件上传

@Controllerpublic classUploadController{

@RequestMappin("upload")public String upload(@RequestParam("file") MultipartFile multipartFile, @RequestParam(value = "desc", required = false) String desc){

System.out.println(desc);for(MultipartFile file: multipartFile){if(!file.isEmpty()){

System.out.println(file.getOriginalFilename());

multipartFile.transferTo(new File("d:\\file\\" +multipartFile.getOriginalFilename()));

}

}return "success";

}

}

拦截器和过滤器的区别

b4d1687843f9b3bc8826317ad70c6417.png

81c6aab406979d69b66a8bf5c073efdd.png

springmvc.xml

8f4759d5e68d86135be01e31e76a2e98.png

执行顺序,preHandler->目标方法->postHandler->页面跳转->afterCompletion

如果执行过程中抛出异常,那么afterCompletion依然会继续执行

执行顺序

e86ed41fb70c1e8dbfd0e3ddcedb48dc.png

public class MyInterceptor implementsHandlerInterceptor{public booleanpreHandle(HttpServletRequest request, HttpServletResponse response){

System.out.println(this.getClass().getName());return true;//返回指控制流程是否停止

}public booleanpostHandle(HttpServletRequest request, HttpServletResponse response){

System.out.println(this.getClass().getName());return true;

}public booleanafterCompletion(HttpServletRequest request, HttpServletResponse response){

System.out.println(this.getClass().getName());return true;

}

}

@Controllerpublic classInterceptorController{

@RequestMapping("/testInterceptor")publicString testInterceptor(){//如果此处抛出异常, after依然会执行

System.out.println(this.getClass().getName());return "success";

}

}

国际化

login_en_US.properties

e703741f4c1d05f105eb3245f672ba6f.png

login_zh_CN.properties

5d85631a2dfa2da056141e3d1ae8b44a.png

jsp文件body内容

42adbacd5e37abac620cc0f63757acac.png

b511339e9221d090b0d2e4b7e9ea0af4.png

springmvc.xml

2cdd093b75de6917e5e13aab8346e6f1.png

jsp文件的body标签前不要漏下以下配置

4e39821af14c552b36142a1dc9e3ad23.png

@Controllerpublic classI18nController{

@AutowiredprivateMessageSource messageSource

@RequestMapping("/i18n")publicString i18n(Locale locale){

System.out.println(locale);

String username= MessageSource.getMesssage("username", null, locale);

System.out.println(username);return "login";

}

@RequestMapping("/i18n")public String i18n(@RequestParam("locale") String localStr, Locale locale, HttpSession session){

Locale locale1= null;

System.out.println(locale);if(localStr != null && !"".equals(localStr)){

locale1= new Locale(localStr.split("_")[0], localStr.split("_")[1]);

}else{

locale1=locale;

}

session.setAttribute(SessionLocaleResolver.class.getName() + ".LOCALE", locale1);return "login";

}

}public class MyLocaleResolver implementsLocaleResolver{publicLocale resolveLocale(HttpServletRequest request){

Locale locale= null;

String localeStr= request.getParameter("locale");if(localeStr != null && !"".equals(localStr)){

locale= new Locale(localeStr.split("_")[0].localeStr.split("_"))

}else{

locale=request.getLocale();

}returnlocale;

}

}

mvc异常处理机制

容器启动好后,进入DispatcherServlet之后,会对HandlerExceptionResolver进行初始化操作

可以通过@ControllerAdvice注解进行标注,表示为全局异常处理类

如果有了全局异常,若当前类抛出了异常会现在本类查找,然后再查找全局异常

@Controllerpublic classExceptionController{

@RequestMapping("/exception1")publicString exception(){

System.out.println(this.getClass().getName());int i = 10/0;return "success";

}

@ExceptionHandler(value= ({ArithmeticExcepton.class, NullPointerException.class}))publicString handlerException(Exception exception){

ModelAndView mv= newModelAndView();

mv.setViewName("error");

mv.addObject("exce", exception);returnmv;

}

@ExceptionHandler(value= (Exception.class))publicString handlerException2(Exception exception){

ModelAndView mv= newModelAndView();

mv.setViewName("error");

mv.addObject("exce", exception);returnmv;

}

}

@ControllerAdvicepublic classMyGlobalExceptionHandler{

@ExceptionHandler(value= ({ArithmeticExcepton.class, NullPointerException.class}))publicString handlerException(Exception exception){

ModelAndView mv= newModelAndView();

mv.setViewName("error");

mv.addObject("exce", exception);returnmv;

}

@ExceptionHandler(value= (Exception.class))publicString handlerException2(Exception exception){

ModelAndView mv= newModelAndView();

mv.setViewName("error");

mv.addObject("exce", exception);returnmv;

}

}

ResponseStatus

@Controllerpublic classExceptionController{

@ResponseStatus(reason= "", value =HttpStatus.NOT_ACCEPTABLE)

@RequestMapping("/exception")publicString handlerException(Exception exception){

System.out.println("exception")return "success";

}

}

@ResponseStatus,可以标注在方法中,但是不推荐使用

@Controllerpublic classExceptionController{

@RequestMapping("/exception")publicString handlerException(String username){

System.out.println("exception")if("admin".equals(username)){return "success";

}else{throw newUsernameException();

}return "success";

}

}

Springmvc流程图

2d1a5d1bb7ac5cd38b7ee038bb56f41e.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/1010920
推荐阅读
相关标签
  

闽ICP备14008679号