java过滤器获取参数_web过滤器中获取请求的参数(content-type:multipart/form-data)

1.前言:

1.1 在使用springMVC中,需要在过滤器中获取请求中的参数token,根据token判断请求是否合法;

1.2 通过requst.getParameter(key)方法获得参数值;

这种方法有缺陷:它只能获取  POST 提交方式中的Content-Type: application/x-www-form-urlencoded;

HttpServletRequest request=(HttpServletRequest) req;

String param= request.getParameter("param");

2.问题:

在一般的请求中,content-type为:application/x-www-form-urlencoded;在此种请求中,使用request.getParam(key)方法可以获取到key对应的属性值;

因为最近涉及到文件的上传操作,上传文件的请求中content-type为:multipart/form-data;此种请求无法直接用request.getParam(key)获取对应的属性值,request中获取的属性值全部为空,无法正常获取;

3.问题描述:

3.1 在web.xml中配置的过滤器

requestFilter

util.web.RequestFilter

requestFilter

/*

3.2  过滤器RequestFilter.java中获取token做匹配

在如下过滤器中,上传文件中的content-type:multipart/form-data使用获取request.getParameter(key)无法获取相应的值。需要借助Spring框架中的CommonsMultipartResolver.resolveMultipart(HttpServletRequest request)将request转为MultipartHttpServletRequest,从而使用getParameter(key)方法获取指定的值;

*在将对象转化完成后,要将转化完成的对象赋值给过滤链中的request参数中,即如下代码中的  req = multiReq; 赋值完成很重要,否则在controller层中依旧无法获取其他参数。

如果不需要再filter中获取请求中的值,则无需如下的操作,在请求经过springMVC框架后,自动会识别请求方式,如果是文件请求,会自动调用CommonsMultipartResolver.resolveMultipart(HttpServletRequest request)方法转化;

packageutil.web;public class RequestFilter implementsFilter {

protectedFilterConfig filterConfig;protected booleanfilterEnabled;protected intlogLevel;protected booleanneedVCode;protected List noFilerList =null;private CommonsMultipartResolver multipartResolver = newCommonsMultipartResolver();publicRequestFilter() {this.filterConfig = null;this.filterEnabled = true;this.logLevel = -1;

}

@Overridepublic voiddestroy() {//TODO Auto-generated method stub

}

@Overridepublic voiddoFilter(ServletRequest req, ServletResponse resp,

FilterChain chain)throwsIOException, ServletException {if(this.filterEnabled){

HttpServletRequest httpReq=(HttpServletRequest)req;

HttpServletResponse httpResp=(HttpServletResponse)resp;

String ctxPath=httpReq.getContextPath();

String requestUri= httpReq.getRequestURI(); //请求的全路径,比如:

String uri = requestUri.substring(ctxPath.length());//全路径除去ctxPath

String tarUri =uri.trim();

String operatorHtmlModel= (httpReq.getHeader("referer")!=null?httpReq.getHeader("referer"):"").trim(); //获取当前页面的url,判断url是否是后台而url(后台的html就两个)//不在过滤列表里的url请求,过滤列表包括t_sys_filter表中数据及visitor角色用户下的授权页面

if(!this.isInNoFilerList(tarUri)){

UserInfo uInfo=SessionUtil.getCurrentUser();

LoginAccount regAccout=SessionUtil.getCurrentPlateLoginAccount();int type = 0 ;//平台账号未登录

if(operatorHtmlModel.endsWith(Const.LOGIN_TYPE_HTML[0])||operatorHtmlModel.endsWith(Const.LOGIN_TYPE_HTML[1])){

type= 1;//后台账号未登录

}//int type = (SessionUtil.getAttribute(Const.LOGIN_TYPE)!=null)?Integer.valueOf(SessionUtil.getAttribute(Const.LOGIN_TYPE).toString()):0;

if(regAccout==null){//平台账号未登录

if(tarUri.endsWith(".do")){

httpResp.sendRedirect(ctxPath+"/"+Const.TIMEOUT_SERVICE);return;

}else if(tarUri.endsWith("/")){

httpResp.sendRedirect(ctxPath+"/"+Const.INDEX_PAGE);return;

}

}else{//平台账号登录

if(tarUri.endsWith("/")){

httpResp.sendRedirect(ctxPath+"/error/noSecurity.htm");return;

}else if(tarUri.endsWith(".do") && !isWithoutUri(tarUri)){

String contentType= httpReq.getContentType();//获取请求的content-type

String post_csrftoken = "";if(contentType.contains("multipart/form-data")){//文件上传请求 *特殊请求

/*CommonsMultipartResolver 是spring框架中自带的类,使用multipartResolver.resolveMultipart(final HttpServletRequest request)方法可以将request转化为MultipartHttpServletRequest

使用MultipartHttpServletRequest对象可以使用getParameter(key)获取对应属性的值

*/

MultipartHttpServletRequest multiReq =multipartResolver.resolveMultipart(httpReq);

post_csrftoken=multiReq.getParameter(Const.SESSION_CSRFTOKEN);//获取参数中的token

req = multiReq;//将转化后的reuqest赋值到过滤链中的参数 *重要

}else{//非文件上传请求

post_csrftoken=httpReq.getParameter(Const.SESSION_CSRFTOKEN);//获取参数中的token

}//csrf防御:判断是否带token//post_csrftoken=httpReq.getParameter(Const.SESSION_CSRFTOKEN);

String csrftoken=(String)SessionUtil.getAttribute(Const.SESSION_CSRFTOKEN);if(post_csrftoken==null || !csrftoken.equals(post_csrftoken)){//判断为不安全的访问

httpResp.sendRedirect(ctxPath+"/common/goNoSecurity.do");return;

}

}

}//设定网页的到期时间,一旦过期则必须到服务器上重新调用

httpResp.setDateHeader("Expires", -1);//Cache-Control 指定请求和响应应遵循的缓存机制 no-cache指示请求或响应消息是不能缓存的

httpResp.setHeader("Cache-Control", "no-cache");//用于设定禁止浏览器从本地缓存中调用页面内容,设定后一旦离开页面就无法从Cache中再调出

httpResp.setHeader("Pragma", "no-cache");

}

chain.doFilter(req, resp);

}

}

@SuppressWarnings("unchecked")

@Overridepublic void init(FilterConfig cfg) throwsServletException {//初始化操作

}privateBoolean isWithoutUri(String tarUri){

String[] withoutUriStrings= {//无需匹配token的请求

"/common/goNoSecurity.do","/plateFormCommon/isLoginForPlateForm.do","/supplierForPlateForm/getCompanyListByRegId.do"

/*,"/PfTaskFileCtrl/addOrUpdateTaskImgFile1.do"*/

/*,"/PfTaskFileCtrl/addOrUpdateTaskImgFileForUpdate.do"*/};for(String uri:withoutUriStrings){if(uri.equals(tarUri)){return true;

}

}return false;

}

}

3.3 控制层 PfTaskFileCtrl.java

如果在filter中未将转化的request值赋值给过滤链,则在这里无法获取fileType对应的值;

packageplatform.common.controller;/*** mogodb文件上传下载

* 项目名称:outsideeasy

* 类名称:PfTaskFileCtrl

* 创建人:mishengliang

* 创建时间:2016-4-26 下午1:55:19

* 修改人:mishengliang

* 修改时间:2016-4-26 下午1:55:19

*@version**/@Controller

@RequestMapping("PfTaskFileCtrl")public classPfTaskFileCtrl {

@AutowiredprivatePfRegisterAttchedService registerAttchedService;

@AutowiredprivateFileOptService fileService;

@AutowiredprivatePfUpdateRegisterAttchedService updateRegisterAttchedService;

@AutowiredprivateCompanyForPlateFormService companyForPlateFormService;

@RequestMapping(value= { "/companyImageView" }, method ={ RequestMethod.GET })publicModelAndView gojsp_companyImageView(ModelAndView modelAndView ){

modelAndView.setViewName("/companyWindow/companyImageView");returnmodelAndView;

}/*** @Description:企业文件上传

* PfTaskFileCtrl

* addOrUpdateTaskImgFile1

*@paramrequest

*@paramresponse

*@return*@throwsException String

*@authoryukai

* 2016-8-4 上午10:03:00*/@DocLogger(explain="企业文件上传")

@RequestMapping(value="addOrUpdateTaskImgFile1",method=RequestMethod.POST)

@ResponseBodypublic String addOrUpdateTaskImgFile1(HttpServletRequest request,HttpServletResponse response) throwsException{

Map qryParam =WebUtil.getDefaultParamsMap(request);

LoginAccount regAccount=SessionUtil.getCurrentPlateLoginAccount();

Map params=new HashMap();

JSONObject json= newJSONObject();

json.put("success", true);/** 1.检查参数*/

if(regAccount == null){//获取任务id

json.put("message", "未登录");returnjson.toString() ;

}

// *如果在filter中未将转化的request值赋值给过滤链,则在这里无法获取fileType对应的值if(WebUtil.isEmpty(request.getParameter("fileType"))){//获取任务id

json.put("message", "没有文件类型值");returnjson.toString() ;

}/**2.赋值*/

int fileType = Integer.parseInt(request.getParameter("fileType"));

String fileName= request.getParameter("fileName");

String formatType= request.getParameter("formatType");

PfRegisterAttched pfRegisterAttched= newPfRegisterAttched();

pfRegisterAttched.setFile_type_id(fileType);//文件类型值

pfRegisterAttched.setFile_name(fileName);//文件名

if(fileName.indexOf(",") != -1){

json.put("message", "文件名中存在非法字符(英文逗号),请先去除后上传");returnjson.toString() ;

}/** 3.对文件信息的处理*/MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;if(WebUtil.isEmpty((CommonsMultipartFile) multipartRequest.getFile("file"))){

json.put("message", "没有文件");returnjson.toString() ;

}

CommonsMultipartFile file= (CommonsMultipartFile) multipartRequest.getFile("file"); //对应前台文件对象

if(file!=null && file.getSize()>0){//检查文件大小和格式

if (file.getSize() >5*1024*1024) {

json.put("message", "文件太大,超过5M");returnjson.toString() ;

}

String originalName=file.getOriginalFilename();

String this_suffix= "";

params.put(Const.ISIMG,0);

params.put(Const.USE_TYPE, fileType);

params.put(Const.USERNAME, regAccount.getLogin_name());

params.put(Const.COM_ID, qryParam.get("companyId"));

params.put(Const.COM_NAME,companyForPlateFormService.getCompanyNameByCompanyId(qryParam));boolean flag=false;//默认不 是图片//获取文件后缀,与传过来的参数file_name重新组装文件名

if(originalName.indexOf(".")>0){//有后缀 XX.jpg XX.RAR

this_suffix=originalName.substring(originalName.lastIndexOf("."));

String[] format= null;if("image".equals(formatType)){//判断上传文件的类型:image 图片,text 文档

format =Const.imgArray;

params.put(Const.ISIMG,1);

}else if("text".equals(formatType)){

format=Const.otherArray;

}for(String suffix:format){if(suffix.equalsIgnoreCase(this_suffix)){

flag=true;break;

}

}

}if(!flag){

json.put("message", "不是指定格式");returnjson.toString() ;

}else{/** 4.进行信息的处理*/Date date= newDate();

SimpleDateFormat sf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String mongodbId=fileService.SaveFile(file,params);

pfRegisterAttched.setMogodb_id(mongodbId);//把存储mongoDb的文件序号存到数据库中

pfRegisterAttched.setCreate_dt(date);

pfRegisterAttched.setFile_format(this_suffix);

Integer id= registerAttchedService.addAppRegisterAttched(pfRegisterAttched);//获取存入信息的id

json.put("fileId",id);

json.put("mongodbId", mongodbId);

json.put("creatDate", sf.format(date));

json.put("message", "上传成功");

}

}else{

json.put("message", "文件不存在");

}returnjson.toString();

}

}

4.解决方案

在问题描述中已有问题解决方案。

此方法主要利用了Spring框架中已有的工具类。

5.总结

5.1 不同的content-type请求获取参数值的方法不同。

5.2 在multipart/form-data请求方式中,需要利用SpringMVC框架中的CommonsMultipartResolver类包装转化为MultipartHttpServletRequest获取参数值;

6. 参考学习

1. servlet3.0 Tomcat7.0 简洁方案

如果使用的是servlet3.0及以上版本,multipart/form-data请求方式取值可以使用 HttpServletRequest.getPart(key)方法获取指定值;

2.通常的三种请求方式获取值方法

* application/x-www-form-urlencoded

*application/json

* text/xml

可以使用将请求转化为流,再转为字符串获取相应的值,通过如下方法获取的字符串获取指定的参数值;

转化方法如下:

/*** 获取请求Body

*

*@paramrequest

*@return

*/

public staticString getBodyString(ServletRequest request) {

StringBuilder sb= newStringBuilder();

InputStream inputStream= null;

BufferedReader reader= null;try{

inputStream=request.getInputStream();

reader= new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));

String line= "";while ((line = reader.readLine()) != null) {

sb.append(line);

}

}catch(IOException e) {

e.printStackTrace();

}finally{if (inputStream != null) {try{

inputStream.close();

}catch(IOException e) {

e.printStackTrace();

}

}if (reader != null) {try{

reader.close();

}catch(IOException e) {

e.printStackTrace();

}

}

}returnsb.toString();

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值