struts2 request.getInpustream()およびmultipartアップロードでデータが取得できないソリューション
この問題は、以前にプロジェクトで発生し、解決されたもので、今日記録します.プロジェクトで遭遇する要件は,ブロックでpostを要求してきたデータストリームを解析し,解析した各パラメータをstruts 2のvalueStackに手動で押し付けることである.postからのデータストリームは、json列形式(クライアントがcontent-typeをマークしていない)またはmultipart/form-data形式で送信された音声ファイルである可能性があります.(バイナリ)とjson列の2つの場合.私の実現構想は、requestがmultipartであればcommons-fileを用いて音声データとjson列を分解し、そうでなければgetInputStreamを直接使用してjson列を取り出すことであると判断することである.
ただし、送信されたデータがmultipart/form-data形式である場合、requestから解析されたファイル(FileItem)リストが空であることが判明する
Multipartリクエストの一部のコードを取得するには、次のようにします.
送信データに誤りがないことが判明した後、ネット上で資料を検索すると、元々、ここのrequestはstruts 2によってカプセル化されており、もはやオリジナルのサーブレットリクエストではないので、このrequestはサーブレットFileUploadによって解析できないため、リストが空になり、解決策はstruts 2にカプセル化されていないrequestを使用してstruts.xmlでファイルアップロードで使用するrequest解析器を指定します.以下のようにします.
しかし、json列を取得する際にrequestが使用されていることが判明する.getInputStream()で取得したデータもnullとは.(/(ㄒoㄒ)/~~~本当に災いが重なって、なぜstruts 2を使うのか)、struts 2で渡されるメッセージのcontent-typeを設定しなければならない(例えばクライアントがjsonを送信し、content-typeがapplication/jsonであるべきである)、そうしないとstruts 2にブロックされ、requestのParameterMapに置かれるが、私はサービス側であるだけなので、クライアントが送信データバンドはcontent-typeを持たない私の制御を受けないで、クライアントバンドがcontent-typeを持たないに関わらず、私の側はすべて互換性がある必要があります(/(ㄒoㄒ)/~~~~~))、伝送する要求メッセージの体はKey=valueのような形式ではなく、jsonなので、このjsonはParameterMapの最初のkeyの中に置かれるべきで、そこで私はSet=requestを使います.getParameterMap().keySet()は,このkeyを巡る最初の要素,すなわちjson列を用いて,これが正しいことを実証した.そこで問題が解決する.
以下に、特定のカスタムブロッキングコードを示します.
ただし、送信されたデータがmultipart/form-data形式である場合、requestから解析されたファイル(FileItem)リストが空であることが判明する
Multipartリクエストの一部のコードを取得するには、次のようにします.
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
items = upload.parseRequest(request);
送信データに誤りがないことが判明した後、ネット上で資料を検索すると、元々、ここのrequestはstruts 2によってカプセル化されており、もはやオリジナルのサーブレットリクエストではないので、このrequestはサーブレットFileUploadによって解析できないため、リストが空になり、解決策はstruts 2にカプセル化されていないrequestを使用してstruts.xmlでファイルアップロードで使用するrequest解析器を指定します.以下のようにします.
のcom.dear.vpInterface.utils.RequestParseWrapperは、独自に実装されたクラスです.package com.dear.vpInterface.utils;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;
public class RequestParseWrapper extends JakartaMultiPartRequest {
// parse , request
@Override
public void parse(HttpServletRequest request, String saveDir)
throws IOException {
}
}
これで上記のデータは解決します.しかし、json列を取得する際にrequestが使用されていることが判明する.getInputStream()で取得したデータもnullとは.(/(ㄒoㄒ)/~~~本当に災いが重なって、なぜstruts 2を使うのか)、struts 2で渡されるメッセージのcontent-typeを設定しなければならない(例えばクライアントがjsonを送信し、content-typeがapplication/jsonであるべきである)、そうしないとstruts 2にブロックされ、requestのParameterMapに置かれるが、私はサービス側であるだけなので、クライアントが送信データバンドはcontent-typeを持たない私の制御を受けないで、クライアントバンドがcontent-typeを持たないに関わらず、私の側はすべて互換性がある必要があります(/(ㄒoㄒ)/~~~~~))、伝送する要求メッセージの体はKey=valueのような形式ではなく、jsonなので、このjsonはParameterMapの最初のkeyの中に置かれるべきで、そこで私はSet=requestを使います.getParameterMap().keySet()は,このkeyを巡る最初の要素,すなわちjson列を用いて,これが正しいことを実証した.そこで問題が解決する.
以下に、特定のカスタムブロッキングコードを示します.
package com.dear.vpInterface.interceptor;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts2.StrutsStatics;
import com.dear.vpInterface.helper.InterException;
import com.dear.vpInterface.utils.JsonUtil;
import com.dear.vpInterface.utils.NameUtil;
import com.dear.vpInterface.utils.PropertyUtil;
import com.dear.vpInterface.utils.HttpError;
import com.dear.vpInterface.utils.StreamUtil;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;
public class MessageFormatInterceptor extends AbstractInterceptor{
private static final long serialVersionUID = 1L;
private static final String INTER_EXCEPTION = "interException";
@Override
public String intercept(ActionInvocation invocation) throws Exception{
ActionContext ctx = invocation.getInvocationContext();
HttpServletRequest request= (HttpServletRequest) ctx.get(StrutsStatics.HTTP_REQUEST);
ValueStack stack = ctx.getValueStack();
Map reqMap = null;
try{
reqMap = getMapFromRequestJson(request);
}catch(InterException e){
request.setAttribute("exception", e);
return INTER_EXCEPTION;
}
setParam2Stack(reqMap, stack);
}
return invocation.invoke();
}
// Map
public Map getMapFromRequestJson(HttpServletRequest request) throws InterException{
String reqJson = null;
byte[] voiceByte = null;
boolean isVoiceByteExisted = false;
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
try {
if (isMultipart == true) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
items = upload.parseRequest(request);
Iterator iterator = items.iterator();
while (iterator.hasNext()) {
FileItem item = iterator.next();
if (item.isFormField()) {
InputStream inputStream = item.getInputStream();
reqJson = StreamUtil.stream2String(inputStream);
} else {
voiceByte = getFile(item);
isVoiceByteExisted = true;
}
}
}else{
reqJson = StreamUtil.stream2String(request.getInputStream()); // Content-Type
if(reqJson == null || "".equals(reqJson)){ // Content-Type
Set set = request.getParameterMap().keySet();
Iterator it = set.iterator();
if(it.hasNext()){
reqJson = it.next();
}
}
}
} catch (IOException e) {
throw new InterException(HttpError.SMB_HTTP_INPUT_JSON_ERROR);
} catch (FileUploadException e) {
throw new InterException(HttpError.SMB_HTTP_INPUT_JSON_ERROR);
}
Map reqMap = JsonUtil.getMap4Json(reqJson);
if(isVoiceByteExisted){
reqMap.put("voiceByte", voiceByte);
}
return reqMap;
}
//
public void setParam2Stack(Map reqMap,ValueStack stack){
boolean isVpIdContained = false;
String value = null;
for(String key : reqMap.keySet()){
// json java
stack.setValue(NameUtil.underlineToCamel(key), reqMap.get(key));
}
}
protected static byte[] getFile(FileItem item) throws IOException {
InputStream in = item.getInputStream() ;
ByteArrayOutputStream outStream = new ByteArrayOutputStream() ;
byte[] data = new byte[64*1024] ;
int count = -1 ;
while((count = in.read(data,0,1024)) != -1){
outStream.write(data, 0, count) ;
}
byte[] fileByte = outStream.toByteArray();
in.close();
outStream.close();
return fileByte;
}
}