关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

java:SpringMVC

发布时间:2020-03-16 00:00:00

   1. SpringMVC控制器业务操作

在SpringMVC第二节中我们了解到mvc控制器处理页面url请求返回响应视图,除了这些操作外,控制器还需要处理更重要的业务,如:接收前台页面传递的参数、绑定数据到页面、返回json数据、文件上传、文件下载等业务操作。

1.1.参数接收 1.1.1.  配置请求编码过滤器

SpringMVC框架本身没有处理请求编码,在前台参数接收Post请求的时候,可能会出现编码乱码的问题,而Spring框架为我们提供了一个请求编码过滤器,我们只需要在web.xml中配置一个请求编码过滤器即可:

web.xml中配置UTF-8编码如下:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">配置post请求编码乱码处理过滤器--><filter><filter-name>characterEncodingFilterfilter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class><init-param><param-name>encodingparam-name><param-value>UTF-8param-value>init-param>filter><filter-mapping><filter-name>characterEncodingFilterfilter-name><url-pattern>/*url-pattern>filter-mapping>web-app>

1.1.2.  参数接收方式

GET接收方式:

①    使用方法的形参接收:注意形参要和请求参数一致;

@Controller
@RequestMapping(value = "/paramController", method = RequestMethod.GET)public class ParamRecCotroller {/**
 * 参数接收方式一:使用形参接收,前台get请求传入的参数名和方法接收的参数名保持一致
 * @param username
 * @param age */@RequestMapping("/insert")public void insert(String username, Integer age){
    System.out.println(username);
    System.out.println(age);
}
}

前台get参数传递方式:

http://localhost:8080/paramController/insert?username=”青海”&age=21

获取到的参数信息:

 

②    如果形参名称和前台传入的参数名不一致,需要使用@RequestParam(value=”前台参数名”)进行映射对应;

@Controller
@RequestMapping(value = "/paramController", method = RequestMethod.GET)public class ParamRecCotroller {/**
 * 参数接收方式二:前台get传递的参数url与方法形参某个参数不一致,需要使用@@RequestParam(value = "前台参数名")
 * @param username
 * @param age */@RequestMapping("/insert")public void insert(@RequestParam(value = "name") String username, Integer age){
    System.out.println(username);
    System.out.println(age);
}
}

前台get参数传递方式:

http://localhost:8080/paramController/insert?name=”青海”&age=21

获取到的参数信息:

 

③    直接使用一个Domain对象接收前台参数,会根据Domain中的属性来进行匹配装值;

@Controller
@RequestMapping(value = "/paramController", method = RequestMethod.GET)public class ParamRecCotroller {/**
 * 参数接收方式三:直接使用一个Domain对象来接收前台参数,每个前台参数必须和User里面的属性名保持一致(前台参数直接映射属性),
 * 不然无法获取对应的参数值,而且必须保证User内有一个无参数的构造器
 * @param user */@RequestMapping("/insert")public void insert(User user){
    System.out.println(user);
}
}

对应Domain中的User类:

public class User {private String username;private Integer age;private String password;public User() {
    }public User(String username, Integer age, String password) {this.username = username;this.age = age;this.password = password;
    }public String getUsername() {return username;
    }public void setUsername(String username) {this.username = username;
    }public Integer getAge() {return age;
    }public void setAge(Integer age) {this.age = age;
    }public String getPassword() {return password;
    }public void setPassword(String password) {this.password = password;
    }

    @Overridepublic String toString() {return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                ", password='" + password + '\'' +
                '}';
    }
}

前台get参数传递方式:

http://localhost:8080/paramController/insert?username=”青海”&age=21&password= 3454

获取到的参数信息:

④    使用原始的HttpServletRequest来获取请求参数信息;

@Controller
@RequestMapping(value = "/paramController", method = RequestMethod.GET)public class ParamRecCotroller {/**
 * 参数接收方式四:直接使用HttpServletRequest获取
 * @param request */@RequestMapping("/insert")public void insert(HttpServletRequest request){
    String username = request.getParameter("username");
    Integer age = Integer.valueOf(request.getParameter("age"));
    String pwd = request.getParameter("pwd");
    System.out.println(username);
    System.out.println(age);
    System.out.println(pwd);
}
}

前台get参数传递方式:

http://localhost:8080/paramController/insert?username=”青海”&age=21&pwd= 3454

获取到的参数信息:

⑤    Restful风格请求参数传递:直接在映射地址上使用{id}占位符,id表示传递的参数名,方法接收时对方法的形参使用@PathVariable(“id”),这里面的id应该和映射地址上的id名称保持一致;

@Controller
@RequestMapping(value = "/paramController", method = RequestMethod.GET)public class ParamRecCotroller {/**
 * 参数接收方式四:前台请求地址中包含id参数信息,使用restful风格映射对应相同的提取参数
 * 注意:前台参数名称必须与restful风格的参数一一对应,名称一致
 * @param idVal */@RequestMapping("/insert/{id}")public void getUserById(@PathVariable(value = "id") Integer idVal){
    System.out.println(idVal);
}
}

前台get参数传递方式:

http://localhost:8080/paramController/insert/5

获取到的参数信息:

 

1.2.数据传递

简单地说,就是使用SpringMVC中Controller向前台页面传递数据。使用Controller进行数据传递的方式主要有四种传递方式:

①    通过ModelAndView对象传递

@Controller
@RequestMapping("/dataController")public class DataTransController {/*** 页面展示返回数据方式一:通过ModelAndView对象传递
    * setViewName:返回一个结果视图
    * addObject(name, value):可以通过name到对应的显示页面上去取数据,value表示显示的数据,
    * 也可以传递对象来取值
* @return*/@RequestMapping("/getData")public ModelAndView getDataRes(){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("msg", "随便写一个msg信息");
    modelAndView.setViewName("/WEB-INF/views/dataView.jsp");
    User user = new User("青海", 21, "2332");
    modelAndView.addObject("user", user);return modelAndView;
}
}

对应jsp页面取值:

<body>${msg}<br/>${user}<br/>${user.username}<br/>${user.age}<br/>${user.password}<br/>body>

对应页面展示数据信息如下:

②    通过Model对象进行数据传递;

@Controller
@RequestMapping("/dataController")public class DataTransController {/**
 * 页面展示返回数据方式二:通过Model对象传递
 * return:返回一个结果视图
 * addObject(name, value):可以通过name到对应的显示页面上去取数据,value表示显示的数据,
 * 也可以传递对象来取值
 * @return
 */@RequestMapping("/getModel")public String getModelRes(Model model){
    model.addAttribute("msg", "Model对象的信息");
    User user = new User("青海", 21, "2332");
    model.addAttribute("user", user);return "/WEB-INF/views/modelDataView.jsp";
}
}

对应jsp页面取值:

  ${msg}<br/>
  ${user}<br/>
  ${user.username}<br/>
  ${user.age}<br/>
  ${user.password}<br/>

对应页面展示数据信息如下:

③   通过HttpServletRequest对象进行数据传递;

这种方式与Model对象传递方式类似,就是把参数换成HttpServletRequest对象,调用request.setAttribute(“msg”, 传递信息或者对象信息),这里就不再详细说明;

 

1.3.SpringMVC返回JSON数据 1.3.1. 实现方式

SpringMVC返回JSON数据格式需要导入Jackson的jar包,Jackson是解析JSON和XML的一个框架,简单易用,性能较高。

在项目中我们需要导入Jackson json的工具包,如下:

jackson-annotations-2.5.0.jar

jackson-core-2.5.0.jar

jackson-databind-2.5.0.jar

对应Controller实现方式:

@Controller
@RequestMapping("/jsonController")public class JsonDemoController {
    @RequestMapping("/getJson")//加上@ResponseBody注解,返回值是通过JSON流的方式输出,Springmvc获取返回值,把对象自动转换为JSON//然后通过response.getWriter().print(jsonString)输出在前台页面    @ResponseBodypublic User getJsonUserData(){
        User user = new User("青海", 21, "2332");return user;
    }
}

前台页面进行数据访问,访问地址:http://localhost:8080/jsonController/getJson

同样可以返回一个JSON集合,对应实现如下:

@Controller
@RequestMapping("/jsonController")public class JsonDemoController {
    @RequestMapping("/getJsonList")
    @ResponseBodypublic List getJsonUserLstData(){
        User user1 = new User("青海", 21, "2332");
        User user2 = new User("俊杰", 23, "3306");
        ListuserList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);return userList;
    }
}

前台页面进行数据访问,访问地址:http://localhost:8080/jsonController/getJsonList

1.3.2 日期型数据格式化

在处理日期Date类型的数据,如果后台不进行处理,那么默认返回的是时间戳的json日期格式:比如"birthday":1584261823034,此时需要在Domain的日期get属性方法上加上@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

/**
 * 如果不加JsonFormat,默认返回的日期格式是时间戳:比如"birthday":1584261823034
 * 需要在日期属性Date的getXXX()方法上加上自定义的日期格式@JsonFormat注解
 * @return
 */
 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")  public Date getBirthday() {return birthday;
  }

同理,在前台向后台传入字符串类型的Date数据时,需要在Domain的日期set属性方法上加上@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss"),后台才能接收到对应的Date参数并转换为日期数据到后台

/**
   * 前台Get方式brithday以字符形式传递,需要加上@DateTimeFormat注解,
   * 才能向后台传递Date类型数据
   * @param birthday   */
   @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")   public void setBirthday(Date birthday) {this.birthday = birthday;
   }

1.4.SpringMVC文件上传

SpringMvc自己没有实现文件上传,需要使用apache.commons.fileupload,需要导入文件上传相关的包:

com.springsource.org.apache.commons.fileupload-1.2.0.jar

com.springsource.org.apache.commons.io-1.4.0.jar

 

创建FileUploadController:

@Controller
@RequestMappingpublic class FileUploadController {//通过get请求,返回一个文件上传的jsp页面--结果视图@RequestMapping(value = "/upload", method = RequestMethod.GET)public String uploadFileGet(){return "/WEB-INF/views/upload.jsp";
    }//文件上传的实现方法@RequestMapping(value = "/upload", method = RequestMethod.POST)public String uploadFilePost(String name, MultipartFile imge, HttpServletRequest request) throws IOException {//获取上传文件的原始文件名String oriFilename = imge.getOriginalFilename();//获取文件名的后缀String suffix = FilenameUtils.getExtension(oriFilename);//产生一个随机的文件名String uuidName = UUID.randomUUID().toString();
        String fileName = uuidName + "." +suffix;//获取文件的保存路径String fileDir = request.getServletContext().getRealPath("/upload");//使用File流来写入文件File file = new File(fileDir, fileName);//文件夹不存在,就创建一个保存路径if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }//IO流的拷贝IOUtils.copy(imge.getInputStream(), new FileOutputStream(file));return "/WEB-INF/views/upload.jsp";
    }
}

准备jsp上传页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>文件上传页面title>head><body><!—文件上传:必须写:enctype="multipart/form-data"—><form action="/upload" method="post" enctype="multipart/form-data">用户名:<input type="text" name="name"/><br/>头像:<input type="file" name="imge"/><br/><input type="submit" value="提交"/>form>body>html>

在applicationContext-mvc.xml中配置multipartResolver:

配置文件上传解析器:id="multipartResolver",这个id不能乱写,还可以
        设置一个maxUploadSize属性,就是上传文件的大小--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize"><value>2000000000value>property>bean>

1.5. ViewResolver视图解析器

前面我们在Controller中返回ModelAndView结果视图时,如果是多个方法,需要一一返回结果视图,结果视图重复的内容还是需要写一遍,比较麻烦:

使用ViewResolver视图解析器配置返回的结果视图.jsp,可以设置视图路径的前后缀,该配置可以让我们写视图路径的时间更加简单。

具体需要在applicationContext-mvc.xml中配置如下内容:

配置默认的视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/" /><property name="suffix" value=".jsp" />bean>

之后在Controller中即可简化视图访问的写法:

@Controller
@RequestMapping("/resolver")public class ResolverController {
    @RequestMapping("/demo1")public ModelAndView demo1(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("resolver_demo1");return  modelAndView;
    }

    @RequestMapping("/demo2")public ModelAndView demo2(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("resolver_demo2");return  modelAndView;
    }
}

对应前台的页面访问:

 

 


/template/Home/Zkeys/PC/Static