目录
1. @ModelAttribute()做数据回显
2. 全局异常处理
3. 拦截器
4.与Json的数据交互
5.springmvc的图片上传
一、@ModelAttribute()做数据的回显
因为@ModelAttribute()会在controller中的方法执行前被执行。所以。如果controller中有多个URL映射的,要小心使用
- 注解无返回值方法void
在页面请求/helloWorld?name = huang,controller会先执行createModel方法。把传来的参数加入到名为attributeName的model属性中,helloWorld方法被调用后。会返回视图名和封装好的ModelAttribute (注意:一定要传入@ModelAttribute 方法中对应的形参)
@Controller
public class textcontroller{
@ModelAttribute //页面访问的时候,需要有一个参数String传过来。
public void createModel(@RequestParam String name, Model model) {
model.addAttribute("attributeName", name);
}
@RequestMapping(value = "/helloWorld")
public String helloWorld() {
return "helloWorld";
}
}
//页面调用 ${attributeName}
- 注解返回具体类
返回具体的类的类型。如果不用value来指定@ModelAttribute的属性名。则返回类型,就是属性名。
@Controller
public class textcontroller2{
@ModelAttribute //如果指定属性名 @ModelAttribute(value="model1")
public User populateModel() {
User user=new User();
user.setName("huang");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld() {
return "helloWorld.jsp";
}
}
//页面调用
//不设置属性名 ${User.name}
//设置属性名 ${model1.name}
3. @ModelAttribute和@RequestMapping注解同一个方法
这时候的方法返回值不是代表视图名。而是model的属性值。视图名称由RequestToViewNameTranslator根据请求"/helloWorld3.do"转换为逻辑视图helloWorld3。Model属性名称有@ModelAttribute(value=””)指定,相当于在request中封装了key=name,value=huang。
@Controller
public class textcontroller3{
@RequestMapping(value = "/helloWorld3.do")
@ModelAttribute("name")
public String helloWorld() {
return "huang";
}
}
- 注解一个方法的参数
方法helloWorld的参数user的值来源于addName()方法中的model属性。此时如果方法体没有标注@SessionAttributes(“user”),那么scope为request,如果标注了,那么scope为session
也可以从form表单、URL中获取(其实不注解指定也可以获取到)
@Controller
public class textcontroller4{
@ModelAttribute("user")
public User addName() {
return new User("huang","123");
}
@RequestMapping(value = "/helloWorld4")
public String helloWorld(@ModelAttribute("user") User user) {
user.setUserName("can");
return "helloWorld";
}
}
//从form、URL获取
@RequestMapping(value = "/helloWorld5")
public String helloWorld(@ModelAttribute User user) {
return "helloWorld";
}
5. 可以做特定的控制权限管理
需要在基类方法中控制写此注解,需要控制权限的控制器,继承控制器就可以了。
public class BaseController {
@ModelAttribute
public void populateModel() throws Exception {
SysUser user = ContextUtil.getCurrentUser();
if(user.getAccount().equals("admin")){
throw new Exception("没有权限");
}
}
}
@Controller //继承基类
public class Hello2ModelController extends BaseController {
@RequestMapping(value = "/helloWorld7")
public String helloWorld(@ModelAttribute("myUser") User user) {
user.setName("huang");
return "helloWorld.jsp";
}
}
二、全局异常处理器
在系统遇到异常的时候。全局处理器会解析异常类型。
如果是系统的异常,直接取出异常信息在页面上展示。
如果不是系统的异常,需要程序员构造一个异常类型。并返回错误提示信息。
//定义异常处理器。
//只要实现了 HandlerExceptionResolver 接口。就是全局异常处理器
public class exceptioneds implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException( HttpServletRequest request,
HttpServletResponse response , Object handler, Exception ex ){
CustomException cunstomexception = null;
if( ex instanceof CustomException){ //判断异常类型
cunstomexception = (CustomException)ex; //系统异常
}else{
cunstomexception = new CustomException("未知错误");
}
//错误信息
String message = cunstomexception.getMessage();
ModelAndView modelandview = new ModelAndView();
//把错误信息传给页面展示
modelandview.addObject( "message ", message );
//返回页面
modelandview.setViewName("error");return modelandview;
}
}
//在springmvc配置文件上配置全局处理器的bean
<bean class="exceptioneds"></bean> //配置上面类的包路径
三、拦截器
Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。使用拦截器需要几个步骤:
- 定义拦截器 (就是需要HandlerInterceptor接口)
实现HandlerInterceptor接口,需要进行三个方法的重写。各自代表不同的含义
public class handlerinterceptor implements HandlerInterceptor{//实现接口
//(1) 这个方法有 (请求、相应、对象) 进入Handler方法之前执行(用于身份验证、身份授权、)
@Override
public boolean preHandle(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2) throws Exception {
// TODO Auto-generated method stub
//false:表示拦截,不向下执行
//true:表示放行。
return false;
}
//(2) 这个方法有 ModelAndView : 进入Handler之后,返回ModelAndView之前执行:
//应用场景从ModelAndView出发: 将公用的模型数据(比如菜单导航,)在这里传到视图,也可以在这里统一指定视图。
@Override
public void postHandle(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, ModelAndView arg3)throws Exception {
// TODO Auto-generated method stub
}
//(3) 这个方法有异常: 执行Handler之后执行: 应用场景:统一异常处理、统一日志处理。
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
}
- 配置拦截器
配置有两种方法,一是基于HanlerMapping的拦截。二是基于全局的拦截。
//(1)首先需要补全schema约束。(这里可能不全,配置适合自己的jar包的约束)
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation=" http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
//(2) 配置HandlerMapping的拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/Login.action"> //配置请求路径
<bean class="com.handlerinterceptor"></bean> //定义的拦截器的路径
</mvc:mapping>
</mvc:interceptor>
</mvc:interceptors>
//(2)配置全局拦截器。在<mvc:interceptors>根下配置拦截器。
<mvc:interceptors>
<bean class="com.handlerinterceptor"></bean> //全局都会使用这个拦截器
</mvc:interceptors>
四、Json的数据交互
(1) 在开发前需要配置环境。导入对应的jar包
jackson-core、jackson-mapper的jar包
(2) 在配置文件中配置转换器
<mvc:annotation-driven />
(3) 交互转换设置 (两种请求情况)
- 请求是Json,返回Json
//(1) 请求的是Json串,返回Json串
$.ajax({
type = 'post',
url = '/login.action',
contentType : 'application/json;charset=utf-8',
//数据提交的是json串
data : '{"name":"huang","password":123}',
success : function(data){
alert(data);
}
})
//controller方法设置
@RequestMapping(value="login")
public @ResponseBody User getUserJson( @RequestBody User user ){
//@RequestBody 将Json --》 java对象
//@ResponseBody 将java对象 ---》 Json串
return user;
}
- 请求时key/value,返回时Json (默认是key/value)
$.ajax({
type = 'post',
url = '/login.action',
//数据提交的是key/value串
data : 'name=huang & password=123',
success : function(data){
alert(data);
}
})
//controller方法设置
@RequestMapping(value="login")
public @ResponseBody User getUserJson(User user ){
//@ResponseBody 将java对象 ---》 Json串
return user;
}
五、扩展springmvc的图片上传
这里介绍一种方法,也是我自己用的比较多的方法。就是从页面上传图片到server,然后定义图片封装设置类,将图片保存在自己项目中的指定文件夹里。(应该是放到服务器比较好些的。后续改进)- 定义图片封装设置类
public class tools {
public void FileUpload(HttpServletRequest request, MultipartFile file) throws IllegalStateException, IOException {
// 创建保存的路径 项目中有指定的文件夹
String url = "/image";
// 保存真实路径
String realUrl = request.getSession().getServletContext().getRealPath(url);
// 创建真实路径的文件
File newfile = new File(realUrl);
if (!newfile.exists())
newfile.mkdirs();
if (!file.isEmpty()) {
// 直接获取上传图片的名称
String photoname = file.getOriginalFilename();
// 拼接完整路径
String photoFilePath = newfile + File.separator + photoname;
File photoBookFile = new File(photoFilePath);
file.transferTo(photoBookFile); // 转传
}
}
}
- 页面上传form
//一定要指定enctype="multipart/form-data"
<form action="/text.action" method="post" enctype="multipart/form-data">
<input type="file" class="custom-file-input" name="picture">
- controller方法接收并处理
@RequestMapping(value = { "/text" }, method = { RequestMethod.POST })
public String text(@RequestParam(value = "picture", required = false) MultipartFile picture){
//在本类中继承图片封装设置类
this.FileUpload(request, picture);// 图片传入项目文件夹中
return "success.jsp";
}
- 配置文件中配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为10MB -->
<property name="maxUploadSize">
<value>10485760</value>
</property>
</bean>
上面是基本的springmvc。
详细的讲解可以到官网学习:https://docs.spring.io/spring/docs/5.2.2.RELEASE/spring-framework-reference/web.html#spring-web