springmvc_day02
1.常用注解
1. @RequestMapping
建立请求url和处理请求的方法之间的对应关系,重要属性:
name= "/findUser"
method = RequestMethod.POST/DELETE/PUT/GET,restful风格
@Controller //当前类必须被spring容器管理,才能使用springmvc的功能
@RequestMapping(path="/param") //表示一级访问目录
public class ParamController{
@RequestMapping(path="/hello") //表示二级访问目录
public String sayHello(){ ... }
}
2. @RequestParam(name="username")
解决请求参数名称跟参数列表名称不一致问题
public void testRequestParam(@RequestParam(name="username") String name){ ... }
3. @RequestBody
获取POST请求方式的请求体内容
public void testRequestBody(@RequestBody String requestBody){ ... }
eg:username=hello&password=123
4. @PathVariable(name="uid")
作用:用于绑定请求映射url中的占位符。 例如:请求映射url中/delete/{id},这个{id}就是请求映射url占位符。
属性:
value/name: 用于指定 url 中占位符名称。
required:是否必须提供占位符。默认是true,表示如果配置了@PathVariable,就必须有占位符{uid},否则500
@RequestMapping(path="/pathVariable/{uid}")
public void testPathVariable(@PathVariable(name="uid") String uid){ ... }
<a href="pathVariable/5"></a>
{uid}需要与@PathVariable("uid")对应,参数名称无所谓
5.@ResponseBody注解
作用在方法上或者类上
1.告知springmvc,当前方法/类不需要解析为逻辑视图,也就是说不需要视图解析器管理;
2.自动将返回值转换为json数据,并相应到浏览器,相当于response.getWriter().write(json);
2.Restful风格和其他注解
Restful风格:请求路径一样,可以根据不同的请求方式去执行后台的不同方法。
post:增 delete:删 put:改 get:查
1. @RequestHeader
获取指定请求头的值
public String testRequestHeader(@RequestHeader("user-agent") String userAgent ){ ... }
2. @CookieValue
获取指定cookie名称的值
public String testCookieValue(@CookieValue("JSESSIONID") String id){ ... }
3. @ModelAttribute
作用在方法/参数,表示执行任何方法前都会优先执行被@ModelAttribute修饰的方法,相当于前置通知,通常对表单参数的null进行增强;如果请求参数不为null,则使用@ModelAttribute增强会失败,还是原来的值,空字符串也会导致失败
@ModelAttribute
public User showUser(User u1){
u1.setDate(new Date);
return u1;
}
@ModelAttribute
public void showUser(User u1,Map<String,User> map){
u1.setDate(new Date);
map.put("abc", u1);
}
public String testModelAttribute(@ModelAttribute("abc") User u2){ ... }
由于spring默认是单例模式的,所以u1==u2,并且@ModelAttribute只能对null属性进行增强,空字符串都不行
4.@SessionAttribute
作用在类上,用于将指定名称的request域中的数据存入到session域中,通常可以搭配ModelMap使用
@SessionAttribute("user")
5.spring的内置对象,直接写在参数列表
ModelMap
ModelMap extends LinkedHashMap<String, Object>
ModelMap modelMap.addAttribute(String name,Object value);
Object modelMap.get(String name);
ModelMap相当于的map共享数据范围是请求域
3.处理请求方法的返回值
1.1 字符串
controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址,前端控制器再请求转发到物理视图地址。指定逻辑视图名,经过视图解析器解析为 jsp 物理路径: /WEB-INF/pages/success.jsp
public String testSayHello(){
return "success";
}
1.2 void
如果不做任何处理,那么视图解析器会默认解析访问目录名拼接上前缀后缀,eg:/WEB-INF/pages/user/testVoid.jsp
可以通过获取原生ServletAPI: HttpServletRequest request , HttpServletResponse response
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
response.setStatus(302); --重定向只能访问web项目下的资源,WEB-INF目录下的不能访问
response.setHeader("location",request.getContextPath()+"/index.jsp");
response.getWriter().write("<h1>Hello World...</h1>");
1.3 ModelAndView
public ModelAndView testModelAndView(){
ModelAndView mav = new ModelAndView();
mav.addObject(String name,Object value); //用法跟ModelMap一样,共享数据
mav.setViewName("success"); //自动通过视图解析器,拼接转发路径,返回值String底层用的就是mav
return mav;
}
2.返回值String的转发和重定向
public String testSayHello(){
return "forward:/WEB-INF/pages/success.jsp";
return "redirect:/index.jsp" ;
}
注意:重定向不能访问WEB-INF目录下的资源;并且使用关键字来重定向的方式,不需要带上项目名。
特殊用法:一个方法跳转到另外一个方法 redirect/forward:testHello
3.ResponseBody 响应 json 数据
/**代表当前包及其所有子包,/*只能代表当前包下
<mvc:resources mapping="/js/**" location="/js/**">
</mvc:resources> //在springmvc.xml中配置,如果不配置,会导致无法引入jquery文件
$.ajax({
data:'{"username":"zhangsan","password":"123"}', //注意:这里传参必须这样写,否则报错
alert(JSON.stringify(data)); //JSON.stringify()方法可以解析出json字符串
});
public @ResponseBody User testResponseBody(@RequestBody User user){
return user; //使用 @ResponseBody注解,springmvc框架会自动完成java类型json类型的转换
}
4.springmvc完成文件上传案例
文件上传三要素:POST,multipart/form-data,file
1.编写jsp页面
<form action="user/fileUpLoad" method="post" enctype="multipart/form-data">
文件名称:<input type="text" name="picname"/>
上传文件:<input type="file" name="fileUpLoad"/>
<input type="submit" value="提交"/>
</form>
enctype:编码方式,默认是application/x-www-form-urlencoded
multipart:多部分的
2.编写控制器
2.1原生的文件上传案例
@RequestMapping("fileUpLoad")
public String testFileUpLoad(HttpServletRequest request) throws Exception{
//1.1创建一个文件夹,用来存储上传的文件
String path = request.getSession().getServletContext().getRealPath("/uploads");
//1.2判断uploads文件夹是否存在,不存在就创建一个
File file = new File(path);
if(!file.exists()){
file.mkdirs();
}
//2.1获取磁盘文件项工厂对象
DiskFileItemFactory factory = new DiskFileItemFactory();
//2.2获取Servlet文件上传对象
ServletFileUpload upload = new ServletFileUpload(factory);
//2.3解析请求中参数的文件项
List<FileItem> items = upload.parseRequest(request);
//2.4遍历文件项
for(FileItem item : items){
//判断文件项的类型
if(item.isFormField()){
//说明是普通的表单项,不做任何处理
}else{
//说明是文件上传项
//获取这个文件的名称
String fileName = item.getName();
//生成随机UUID,防止304,原生的UUID是8-4-4-12格式的,需要处理掉"-"
String uuid = UUID.randomUUID().toString().replace("-","");
fileName = uuid + "_" + fileName;
//输出文件项到指定目录下
item.write(new File(path,fileName));
//清理缓存
item.delete();
}
}
return "success";
}
2.2基于springmvc的文件上传案例
获取原生serveltPAI: HttpServletRequest request,MultipartFile multipartFile
.... //multipartFile必须跟form表单中的tyep="file" name="multipartFile"对应
String filename = multipartFile.getOriginalFilename(); //获取原始文件名
String uuid = UUID.randomUUID().toString().replaceAll("-","");
filename = uuid + "_" + filename ;
multipartFile.transferTo(new File(realPath,filename));
springmvc.xml中的配置
//id必须叫multipartResolver,否则500
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5242880"> //表示5M
</bean>
2.3跨服务器上传
//创建客户端对象
Client client = Client.create();
//和图片服务器进行连接
WebResource resource = client.resource(path,filename);
//上传文件
resource.put(multipartFile.getBytes());
需要在tomcat的config/web.xml中第108行中设置
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
5.springmvc的异常处理
当服务器出现异常,如果不进行处理,最终会抛给客户端
第一步:自定义一个类实现HandlerExceptionResolver接口
第二步:在springmvc.xml中,将自定义的异常类对象交给springmvc容器管理
6.springmvc的拦截器
过滤器和拦截器的区别:
过滤器是web的三大组件之一,任何web工程都可以使用;过滤器在url-pattern中配置/*后,能对所有的请求进行过滤
拦截器是springmvc提供的,只有使用了springmvc框架才可以使用;拦截器只对控制器中的方法进行拦截
自定义拦截器:
第一步:编写一个普通类实现 HandlerInterceptor 接口
public class MyInterceptor implements HandlerInterceptor{
preHandle(); //return true表示放行,false表示不放行,最先执行的方法
postHandle(); //处理器方法执行完后,再跳转页面前执行该方法
afterCompletion(); //跳转页面后执行该方法
}
执行顺序:preHandle()-->controllerMethod()-->postHandle()-->jspMethod()-->afterCompletion()
第二步:在springmvc.xml中配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"></mvc:mapping> // /**表示拦截所有包下所有请求
<bean id="myInterceptor" class="com.baidu.interceptor.MyInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>