SpringMVC
mvc处理乱码:
①public String isreg(User u,HttpServletRequest request)
②String name = u.getname();
String str = new String(name.getBytes("iso-8859-1"),"utf-8");
获取请求头信息 @RequestHeader
public String requestHeader(@RequestHeader("Accept-Language") String alg) {
通过@RequestMapping("Accept-Language") String alg 获取请求头中的Accept-Language值,并将值保存在alg中
通过mvc获取cookie值(JSESSIONID)
@CookieValue
(前置知识:服务器在接收客户端第一次请求时,会给该客户端分配一个session(该session包含一个sessionid))
小结:SpringMvc处理各种参数的流程/逻辑:
请求:前端发请求a->@RequestMapping("a")
处理请求中的参数xyz:
@RequestMapping("a")
public String aa(@Xxx注解("xyz") xyz){
}
在SpringMVC中使用原生态的Servlet API :HttpServletRequest 直接将servlet-api中的类、接口等写在springMVC所映射的方法参数中即可
处理模型数据
如果跳转时需要到数据:V、M,则可以使用一下方式:
ModelAndView、ModelMap、Map、Mpdel -数据放在了request作用域中
@SessionAttributes、@ModeAttribute
示例:
public String testModel(Model model | Map<String,Object>m){
m.put(x,"..");就会将x对象放在request域中
如何将上述数据放入session中?@SessionAttributes(..)
在方法类的的最上面加@SessionAttributes(..)里面的值可以视具体的值(Student.class)
@@ModeAttribute
i.经常在更新时使用
ii.在不改变原有代码的基础上,插入一个新方法。
通过@ModeAttribute修饰的方法,会在每次请求前先执行;
并且该方法的参数map.put()可以将对象放入即将查询的参数中;
必须满足的约定:
map.put(k,v)其中的k必须是即将查询的方法的参数的首字母小写
testModeAttribute(Student xxx),即student;
如果不一致,需要通过@ModeAttribute声明。如下:
@RequestMapper(value="testModeAttribute") public String testModeAttribute(@ModeAttribute("stu")Student studetn){ student.setName(student.getName()); ... return ..
}
@ModeAttribute会在该类的每个方法执行前均被执行
2.视图、视图解析器
视图的顶级接口:View
视图解析器:ViewResolver
常见的视图和解析器:
InternalResourceView、InternalResourceViewResolver
public class JstView extends InternalResourceView,
如果发现Jsp中包含了jstl语言相关的内容,则自动转为JstView
常见的视图解析器:
InternalResourceView、InternalResourceViewResolver
public class JstlView extends InternalResourceView:
springMVC解析jsp时会默认使用InternalResourceView,如果发现Jsp中包含jstl语言,则会自动转为JstlView。
JstlView可以解析jstl/实现国际化操作
国际化:针对不同地区、不同国家,进行不同的显示
InternalResourceViewResolver其他功能:
index.jsp -> Controller(@RequestMapping('a')) ->succes.jsp
要用SpringMVC实现:index.jsp -> success.jsp:
<!-- 此标签可以省略controller直接访问地址 view-name依旧会加上前缀和后缀 -->
<mvc:view-controller path="tc/testMVCViewController" view-name="success2" />
以上注解,会让所有的请求转入<mvc:..>中匹配映射地址,而会忽略掉@RequestMapping();
如果想让@RequestMapping()和<mvc:...>共存,则需要加入注解:<mvc:annotation-driven></mvc:annotation-driven>
指定跳转方式:return "forward:/index/success.jsp"
springMVC中,url-parttern中使用/让所有的请求都进入mvc的时候,静态资源(图片、js、css等)是不能访问的
要想访问静态资源:
1.在web.xml中,配置servlet-mapping
2.在web.xml中,配置springMVC的DispatcherServlet的访问路径的时候,使用后缀来区分静态资源和其他动态资源请求
3.在app.xml (springMVC的配置文件)中,通过mvc: resources来映射静态资源的访问路径;
4.在app.xml中,指定mvc:default-servlet- handler;
文件上传:
1.通过commons-fileupload.jar和commons-io.jar
2.实现MultipartResolver接口
3.配置app.xml
<!-- 配置文件上传视图解析器 maxUploadSize是限制上传的图片最大字节 dafaultEncoding是设定上传图片编码 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"></property> <property name="defaultEncoding" value="uft-8"></property> </bean>
4.处理方法
@RequestMapping("add") public String addBook(Book book,@RequestParam MultipartFile pic,HttpServletRequest request) { OutputStream os = null; try { //获取储存地址 String realpath = request.getSession().getServletContext().getRealPath("/images/upload"); //获取随机数 String uuid = UUID.randomUUID().toString(); File file = new File(realpath+"/"+uuid+pic.getOriginalFilename()); os = new FileOutputStream(file); FileCopyUtils.copy(pic.getInputStream(), os); book.setImgPath("images/upload/"+uuid+pic.getOriginalFilename()); bookservice.addBook(book); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return "redirect:findPagBooks"; }
文件上传
文件下载:
1.实现ResponseEntity<byte[]>
@RequestMapping(value="download",method=RequestMethod.GET) public ResponseEntity<byte[]> downloadfile(String filename,HttpServletRequest request) { String realPath = request.getSession().getServletContext().getRealPath(filename); File file = new File(realPath); HttpHeaders headers = new HttpHeaders(); //显示弹框,“attachment”为了显示弹框上有文件信息 headers.setContentDispositionFormData("attachment", filename);
2、
@RequestMapping(value="download",method=RequestMethod.GET) public ResponseEntity<byte[]> downloadfile(String filename,HttpServletRequest request) { String realPath = request.getSession().getServletContext().getRealPath(filename); File file = new File(realPath); HttpHeaders headers = new HttpHeaders(); //显示弹框,“attachment”为了显示弹框上有文件信息 headers.setContentDispositionFormData("attachment", filename); /** * 三个参数 * 1.第一个参数写入要响应的内容,这里要做下载,所有响应的内容应该是文件内容,这里准备一个byte[]来保存文件的字节 * 2.第二个参数,用来描述响应头 * 3.第三个参数,表示响应的状态 */ try { return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK); } catch (IOException e) { e.printStackTrace(); } return null; }
/**
* 三个参数
* 1.第一个参数写入要响应的内容,这里要做下载,所有响应的内容应该是文件内容,这里准备一个byte[]来保存文件的字节
* 2.第二个参数,用来描述响应头
* 3.第三个参数,表示响应的状态
*/
try { return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK); } catch (IOException e) { e.printStackTrace(); } return null; }
拦截器
要实现拦截器必须实现一个接口HandlerInterceptor
1.编写拦截器implements HandlerInterceptor
2.配置:将自己写的拦截器配置到springMVC中(.xml)
<mvc:interceptors> <mvc:interceptor> 指定拦截的路径,基于ant风格 <mvc:mapping path="/**"/> 指定不拦截的路径 <mvc:exclude-mapping path="/user/..."/> <bean class="类名路径"></bean> </mvc:interceptor> </mvc:interceptors>
异常处理
1.
SpringMVC:HandlerExceptionResolver接口:
该接口的每一个实现类都是异常的一种处理方式:
ExceptionHandlerExceptionResolver:主要提供了@ExceptionHandler注解,并通过该注解处理异常
//该方法用于捕获本类中抛出的ArrayIndexOutOfBoundsException异常
@ExceptionHandler({ArrayIndexOutOfBoundsException.class}) public String handlerArrayIndexOutOfBoundsException(Exception e,Model model) { System.out.println("============="+e); model.addAttribute("e", e); return "error"; } @ExceptionHandler标识的方法的参数必须在异常类型(Throwable或其子类),不能包含其他类型的参数
异常处理的路径:最短优先
如果有方法抛出一个异常,而该类中有两个对应的异常处理方法,优先级最短优先。
@ExceptionHandler默认只能捕获当前类中的异常方法
如果发生异常的方法和处理异常的方法不在同一个类中:需要添加此注解@ControllerAdvice
总结:如果一个方法用于处理异常,并且只处理当前类中的异常:@ExceptionHandler
如果一个方法用于处理异常,并且只处理所有类中的异常:类前加@ControllerAdvice、处理异常的方法前加@ExceptionHandler
2.
ResponseStatusExceptionResolver:自定义异常显示页面@ResponseStatus
@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="数组越界!!!") public class MyArrayIndexOutException extends Exception{//自定义异常 } @ResponseStatus也可以写在方法的前面
3.
SimpleMappingExceptionResolver:通过配置来实现异常的处理
<!-- SimpleMappingExceptionResolver:通过配置来实现异常的处理 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" > <!-- 异常对象会被保存在exceptionAttribute的value值中;并且会放进request域中 --> <property name="exceptionAttribute" value="ex"></property> <property name="exceptionMappings"> <props> <!-- 相当于catch(ArithmeticException ex){跳转:error} --> <prop key="方法路徑"> error </prop> <prop key="方法路徑"> error2 </prop> </props> </property> </bean>
error.jsp页面接收:${requestScope.ex}