SpringMVC进击

xiaoxiao2021-02-28  42

Spring进击

一、@RequestMapping

通过RequestMapping注解可以定义不同的处理器映射

URL路径映射

@RequestMapping(value=”/test”) 可以不写value值 默认是value值

value值可以是数组,可以将多个url映射到同一个方法中。

窄化请求映射

这个方式是在class上添加@RequestMapping(url)来指定请求前缀,从而限制了此类下的所有方法请求必须以这个url为签注,这个方式能对url进行分类管理,在实际项目中一个模块不可能全由一个人实现,所以很有可能我们自己在类的方法上写的url会重复,我们就可以通过这种方式来避免

举个例子

@Controller @RequestMapping("/user") public class UserTest{ @RequestMapping("/list") public void getList(){ } } 如果我们要访问getList() 我们的访问地址就是/user/list

限制请求方法

限定GET方法

@RequestMapping(method = RequestMethod.GET)

如果通过Post访问则报错:

HTTP Status 405 - Request method ‘POST’ notsupported

例如:

@RequestMapping(value=”/test”,method=RequestMethod.GET)

限定POST方法

@RequestMapping(method = RequestMethod.POST)

如果通过Post访问则报错:

HTTP Status 405 - Request method ‘GET’ notsupported

例如:

@RequestMapping(value=”/test”,method=RequestMethod.POST)

GET和POST都可以

@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})

二、controller方法返回值

返回ModelAndView(掌握)

在controller方法中new 一个ModelAndView对象并返回,对象中我们可以添加Model数据,指定view

modelAndView.addObject(“test”, test); 指定返回页面的数据

modelAndView.setViewName(“index”) 指定返回的页面是index

返回void(破坏 了SpringMVC结构,不建议使用)

可以在controller方法上定义request和response,通过request和response指定响应结果:

使用request.getRequestDispatcher(url).forward(request, response) 转向页面

使用response.sendRedirect(url)重定向

使用response指定响应结果,

例如响应json数据

response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串");

注意:如果controller返回值是void的话,要写页面的完整路径

返回String(推荐使用)

返回逻辑视图名

controller方法返回字符串可以指定逻辑视图名,通过视图解析器(这个通常在xml文件中配置好)解析为物理视图地址

Redirect 重定向

controller方法返回结果重定向到一个url地址,例如我们要重定向到test

return “redirect:test”

redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,因为转发即执行了一个新的request和response。由于新发起一个request原来的参数在转发时就不能传递到下一个url,如果要传参数可以在test后边加参数。

forward 转发

controller方法执行后继续执行另一个controller方法,forward方式相当于 “request.getRequestDispatcher(url).forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和response。所以转发前请求的参数在转发后仍然可以读取到。

三、异常处理器

​ 主要是为了防止项目上线后给用户抛500等异常信息,所以我们必须处理好异常,不然别人会说你个辣鸡,连异常都不处理,抛给我看干什么我又不知道怎么改,真是弱鸡。

异常分为两类:

预期异常

通过捕获异常的到异常信息

运行时异常RuntimeException

通过规范代码开发、测试等手段减少异常的发生

解决异常的方法是自定义全局异常处理器实现HandlerExceptionResolver接口(interface)在SpringMVC.xml文件中配置生效

自定义异常类

为了区分不同的异常,根据异常的类型来自定义异常类,举个例子,在这我创建一个自定义系统异常, 如果有抛出此类异常就是系统预期处理的异常信息

public class MyException extends Exception { /** serialVersionUID*/ private static final long serialVersionUID = -5212079010855161498L; //异常信息 private String message; public MyException(String message){ super(message); this.message = message; } public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } }

自定义异常处理器

// 记得要实现HandlerExceptionResolver接口哦 public class MyExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { // 打印异常信息 exception.printStackTrace(); MyException myException = null; //如果抛出的是系统自定义异常则直接转换 if(exception instanceof MyException){ myException = (MyException)exception; }else{ //如果抛出的不是系统自定义异常则重新构造一个系统错误异常。 myException = new MyException("系统错误!"); } ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message", myException.getMessage()); modelAndView.setViewName("error"); return modelAndView; } }

异常错误界面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>错误页面</title> </head> <body> 您的操作出现错误如下:<br/> ${message } </body> </html>

异常处理器配置(xml中)

在SpringMVC.xml文件中声明

<!-- 异常处理器 --> <bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/>

四、上传图片

这个是为了解决 当你的用户端需要传输图片久而久之造成服务器负载的情况

配置虚拟目录

在Tomcat上配置图片的虚拟目录,在conf/server.xml文件中加入

<Context docBase="存放图片的路径" path=“/pic” reloadable=“false”/>

我们访问 localhost:8080/pic, 即可访问我们存放图片路径下的图片了

依赖

<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>

配置解析器(配置于SpringMVC.xml文件中)

<!-- 文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置上传文件的最大尺寸 --> <property name="maxUploadSize"> <value>5242880</value> </property> </bean>

上传图片

//假设我们用户有一张图片 我们上传一张图片 并把其信息存到用户的信息中 @RequestMapping("/test") public String test(User user, MultipartFile pictureFile)throws Exception{ //原始文件名称 String pictureFile_name = pictureFile.getOriginalFilename(); //新文件名称 防止文件名重复 String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf(".")); //上传图片 File uploadPic = new java.io.File("存放图片的位置"+newFileName); if(!uploadPic.exists()){ uploadPic.mkdirs(); } //向磁盘写文件 pictureFile.transferTo(uploadPic); user.setPic(newFileName); //更新用户在数据库之中的信息 .................. return "success"; }

页面

<form id="userForm" action="${pageContext.request.contextPath }/user/test" method="post" enctype="multipart/form-data"> <input type="hidden" name="pic" value="${user.pic }" /> <tr> <td>商品图片</td> <td> <c:if test="${user.pic !=null}"> <img src="/pic/${user.pic}" width=100 height=100 /> <br/> </c:if> <input type="file" name="pictureFile" /> </td> </tr> </form>

五、json数据的交互

@RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。

List.action?id=1&name=zhangsan&age=12

本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象

@ResponseBody

作用:

该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端

本例子应用:

@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端

请求json,响应json实现

配置依赖

<!-- JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.2</version> </dependency>

配置json转换器

<!--注解适配器 --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> </bean> </list> </property> </bean>

如果使用<mvc:annotation-driven/> 则不用定义上边的内容。

controller

// 提交json信息,响应json信息 @RequestMapping("/submit_RequestJson") public @ResponseBody User submit_RequestJson(@RequestBody User user) throws Exception { System.out.println(user); // 处理 ......................... return user; }

页面上

引入jQuery /请求json响应json function request_json(){ $.ajax({ type:"post", url:"${pageContext.request.contextPath }/user/submit_RequestJson", contentType:"application/json;charset=utf-8", data:'{"name":"test","sex":1}', success:function(data){ alert(data); } }); }

六、Restful

​ Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数

Url格式:http://test/article/details/45621673

资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是post和get。Put和Delete几乎不使用。

how to deploy it

添加DispatcherServlet的rest配置(写于web.xml文件中) <servlet> <servlet-name>springmvc-servlet-rest</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc-servlet-rest</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

进行URL模板模式映射

@RequestMapping(value=”/ viewItems/{id}”):{×××}占位符,请求的URL可以是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。 @PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。

@RequestMapping("/viewItems/{id}") public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{ //方法中使用@PathVariable获取useried的值,使用model传回页面 //调用 service查询商品信息 ItemsCustom itemsCustom = itemsService.findItemsById(id); return itemsCustom; }

如果RequestMapping中表示为”/viewItems/{id}”,id和形参名称一致,@PathVariable不用指定名称。

静态资源访问<mvc:resources>

如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理。

spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。

如下是对js文件访问配置:

<mvc:resources location="/js/" mapping="/js/**"/>

七、拦截器

​ 功能就是和servlet开发中的过滤器Filter类似的,用于对处理器进行预处理和后处理

定义拦截器

实现HandlerInterceptor接口

public class HandlerInterceptor1 implements HandlerInterceptor{ /** * controller执行前调用此方法 * 返回true表示继续执行,返回false中止执行 * 这里可以加入登录校验、权限拦截等 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Return false; } /** * controller执行后但未返回视图前调用此方法 * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * controller执行后且视图返回后调用此方法 * 这里可得到执行controller时的异常信息 * 这里可记录操作日志,资源清理等 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }

拦截器配置

针对某种mapping配置拦截器

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="handlerInterceptor1"/> <ref bean="handlerInterceptor2"/> </list> </property> </bean> <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/> <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

针对所有的mapping配置全局拦截器

<mvc:interceptors> <mvc:interceptor> <!-- 要拦截所有,必须配置为 /** --> <mvc:mapping path="/**" /> <!-- 指定拦截器的位置 --> <bean class="com.lj.interceptor.LoginInterceptor1" id="loginInterceptor" /> </mvc:interceptor> <mvc:interceptor> <!-- 要拦截所有,必须配置为 /** --> <mvc:mapping path="/**" /> <!-- 指定拦截器的位置 --> <bean class="com.lj.interceptor.LoginInterceptor2" id="loginInterceptor" /> </mvc:interceptor> </mvc:interceptors>

针对拦截器举个例子

检测用户是否登录了,没有登录就拦截

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { //判断当前访问路径是否为登录的路径,如果是则放行 if(request.getRequestURI().indexOf("/login") >= 0){ return true; } //判断session中是否有登录信息,如果没有则跳转到登录页面,如果有则放行 HttpSession session = request.getSession(); if(session.getAttribute("username") != null){ return true; } request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); return false; } }

用户登录的controller

//登陆页面 @RequestMapping("/login") public String login(Model model)throws Exception{ return "login"; } //登陆提交 // userid:用户账号,pwd:密码 @RequestMapping("/loginsubmit") public String loginsubmit(HttpSession session,String userid,String pwd)throws Exception{ //向session记录用户身份信息 session.setAttribute("activeUser", userid); return "redirect:user/userShow"; } //退出 @RequestMapping("/logout") public String logout(HttpSession session)throws Exception{ //session过期 session.invalidate(); return "redirect:user/userShow"; }

转载请注明原文地址: https://www.6miu.com/read-2622310.html

最新回复(0)