这篇继续说一下SpringMVC。
SpringMVC中的接收参数方式
1.普通参数
- 在方法中声明相同的名称的形参,通过相同的形参来传入参数
- 参数获取和形参的名称有关,和位置无关
- 如果名称不匹配,使用@RequestParam("name")来进行参数的请求绑定,且是必须要传入的参数
public ModelAndView method02(@RequestParam("name")String username,String password){…}
2.对象参数
- 使用对象来接收参数,调用属性对应的set方法来赋值,(参数名称和成员变量的名称一致)
- 如果请求的参数的日期类型,需要setter使用@DateTimeFormat(pattern="yyyy-MM-dd")
public ModelAndView method04(User user){…}
3.HttpServletRequest接收参数(springmvc不建议使用,javeWeb使用)
public ModelAndView method05(HttpServletRequest request){…}
4.url地址获取 //restful风格
- 从url中来获取参数
- http://localhost:8080/项目名/请求名/参数1/参数2/参数...
- RESTFUL风格的写法,参数只能是包装类
@RequestMapping("/method06/{name}/{password}/{age}")//注意这个注解
public ModelAndView method06(@PathVariable("name")String name1,
@PathVariable("password")String password,
@PathVariable("age")Long age){…}
SpringMVC页面传递参数的方式:
- 用Model对象:
@RequestMapping("/method01")
public String method01(Model model){
//字符串类型:
//model.addAttribute("username", "张三");
//对象类型:
//model.addAttribute("user", new User(95, "张三"));
//不写key的话,会自动的添加key,名字为类的首字母小写
model.addAttribute(new User(100, "李四"));
return "forward:/WEB-INF/jsps/attribute.jsp";
}
- 用ModelAndView对象:
@RequestMapping("/method02")
public ModelAndView method02(){
ModelAndView mav = new ModelAndView();
mav.addObject("user", new User(8888, "王五"));
mav.setViewName("/WEB-INF/jsps/attribute.jsp");
return mav;
}
- 用JavaWeb Servlet 写法
连续跳转:
@RequestMapping("/method03")
public User method03(){
User user= new User(1, "王五");
return user;
}
@RequestMapping("/attribute/method03")
public String method04(){
return "/WEB-INF/jsps/attribute.jsp";
}
SpringMVC中jsp页面跳转的两种方式:
@Controller
@RequestMapping("/jsp")
public class JspController {
//1.用ModelAndView的setViewName()方法
public ModelAndView method01(){
ModelAndView mav = new ModelAndView();
mav.setViewName("/WEB-INF/jsps/jsp.jsp");
return mav;
}
//2.返回类型为String
@RequestMapping("/method02")
public String methode02(){
return "/WEB-INF/jsps/jsp.jsp";
}
}
为了跳转页面时不要每次都写上全路径而且/WEB-INF/有安全级别,所以可以在applicationContext.xml中配置视图解析器:
<!--配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Springmvc中默认是转发(forward:)
如果要重定向用“redirect:”
mav.setViewName("redirect:/WEB-INF/jsps/view.jsp");
或return "redirect:/WEB-INF/jsps/view.jsp";
注意:在返回页面时加上forward:或redirect:时必须写全路径,包括配置了视图解析器时。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SpringMVC中的上传下载
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
在applicationContext.xml中添加 上传解析器
<!--上传解析 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 可用属性之一; 限制文件大小(以字节为单位)5M -->
<property name="maxUploadSize" value="#{1024*1024*5}"/>
<!--设置上传的默认的编码格式 -->
<property name="defaultEncoding" value="utf-8"/>
</bean>
写入upload上传的页面:注意:是post提交,且enctype="multipart/form-data"不能少
<form method="post" action="/form" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
上传的Controller
@Controller
@RequestMapping("/upload")
public class UploadController {
//@PostMapping("/method01")//同样的路径名:只是接收post请求
@RequestMapping(value="/method01",method=RequestMethod.POST)
public String method02(String name,MultipartFile file ,Model model) {
System.out.println("UploadController post...");
System.out.println(file.getContentType());//类型
System.out.println(file.getOriginalFilename());//文件名字
System.out.println(file.getName());//File对应的引用名
System.out.println(file.getSize());//大小
InputStream inputStream=null;
OutputStream outputStream=null;
try {
inputStream = file.getInputStream();
File savefile= new File("D:/java"+"/"+file.getOriginalFilename());
outputStream = new FileOutputStream(savefile);
//流的写法
/* byte [] bys= new byte[1024];
int len=0;
while ((len=inputStream.read(bys))>0) {
outputStream.write(bys, 0, len);
}*/
//另一种写法
IOUtils.copy(inputStream, outputStream);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
inputStream.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
model.addAttribute("OriginalFilename", file.getOriginalFilename());
return "down";
}
}
下载的Controller:
@Controller
@RequestMapping("/upload")
public class DownController {
@RequestMapping("/down")
public ResponseEntity<byte[]> method01(HttpServletRequest request,String filename) throws IOException {
/**
* 第二种方法下载:也是通用的方法---会用就行,如果忘了怎么写了,可以写io流
*/
System.out.println(filename);
String download="d:/java";
//解决中文的乱码问题
String string = new String(filename.getBytes("iso-8859-1"),"utf-8");
//寻找上传的文件
System.out.println(string);
File file= new File(download+File.separator+string);
//获得请求头
HttpHeaders headers= new HttpHeaders();
//通知浏览器以attachment的方式来打开
headers.setContentDispositionFormData("attachment", string);
//请求头设置 互联网的媒介类型
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
//流的写法
/*String download="d:/java";
File file =new File(download+"/"+filename);
InputStream inputStream=null;
OutputStream outputStream= null;
try {
inputStream= new FileInputStream(file);
outputStream = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\"+filename);
byte [] bys= new byte[1024];
int len=0;
while ((len=inputStream.read(bys))>0) {
outputStream.write(bys, 0, len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
outputStream.close();
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SpringMVC中的拦截器
1.实现HandlerInterceptor
2.重写3个方法: preHandle() postHandle() afterCompletion()
自定义拦截器MyInterceptor.Java
public class MyInterceptor implements HandlerInterceptor{
/**
* 方法之前
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle");
return true;
}
/**
* 方法执行后
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
/**
* 页面渲染后
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion");
}
}
3. applicationContext.xml中配置拦截器的映射:
<!--配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!--所有的请求-->
<mvc:mapping path="/**"/><!--要两个*-->
<!--不拦截什么请求-->
<mvc:exclude-mapping path="/attribute/method02"/>
<bean class="com.chinasofti.controller._11_interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SpringMVC中的异常处理
在一个良好的Rest架构的应用中,所有的异常都应该有对应的Http Status Code来表示具体的异常类型,这样可以客户端可以基于对应的Status Code做出最有利于自己的处理。 在Spring MVC中,异常处理机制有3个选项:
基于Exception的,即只处理某个异常。
基于Controller的,即处理某个Controller中抛出的异常。
基于Application的,即处理该Application抛出的所有异常。【大牛链接】