I am uploading files (of different content types) using Apache fileupload API as follows:
FileItemFactory factory = getFileItemFactory(request.getContentLength());
ServletFileUpload uploader = new ServletFileUpload(factory);
uploader.setSizeMax(maxSize);
uploader.setProgressListener(listener);
List<FileItem> uploadedItems = uploader.parseRequest(request);
... saving files to GridFS using the following method:
public String saveFile(InputStream is, String contentType) throws UnknownHostException, MongoException {
GridFSInputFile in = getFileService().createFile(is);
in.setContentType(contentType);
in.save();
ObjectId key = (ObjectId) in.getId();
return key.toStringMongod();
}
... calling saveFile() as follows:
saveFile(fileItem.getInputStream(), fileItem.getContentType())
and reading from GridFS using the following method:
public void writeFileTo(String key, HttpServletResponse resp) throws IOException {
GridFSDBFile out = getFileService().findOne(new ObjectId(key));
if (out == null) {
throw new FileNotFoundException(key);
}
resp.setContentType(out.getContentType());
out.writeTo(resp.getOutputStream());
}
My servlet code to download the file:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI();
String[] uriParts = uri.split("/"); // expecting "/content/[key]"
// third part should be the key
if (uriParts.length == 3) {
try {
resp.setDateHeader("Expires", System.currentTimeMillis() + (CACHE_AGE * 1000L));
resp.setHeader("Cache-Control", "max-age=" + CACHE_AGE);
resp.setCharacterEncoding("UTF-8");
fileStorageService.writeFileTo(uriParts[2], resp);
}
catch (FileNotFoundException fnfe) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
catch (IOException ioe) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
}
However; all non-ASCII characters are displayed as '?' on a web page with encoding set to UTF-8 using:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
Any help would be greatly appreciated!
Apologies for taking your time! This was my mistake. There is nothing wrong with the code or GridFS. My test file's encoding was wrong.
resp.setContentType("text/html; charset=UTF-8");
Reason: only content type, together with a binary InputStream are passed on.
public void writeFileTo(String key, HttpServletResponse resp) throws IOException {
GridFSDBFile out = getFileService().findOne(new ObjectId(key));
if (out == null) {
throw new FileNotFoundException(key);
}
resp.setContentType(out.getContentType()); // This might be a conflict
out.writeTo(resp.getOutputStream());
}
Related
I would like to get the XML data from request and response and use it into Rest controller. I tried this:
#RestController()
public class HomeController {
#PostMapping(value = "/v1")
public Response handleMessage(#RequestBody Transaction transaction, HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest request, HttpServletResponse response
System.out.println("!!!!!!! InputStream");
System.out.println(request.getInputStream());
System.out.println(response.getOutputStream());
InputStream in = request.getInputStream();
String readLine;
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
}
}
But I get java.io.IOException: UT010029: Stream is closed
What is the proper way to get the content into String variable?
EDIT: I also tried solution with Filter but I'm not aware how to use the request payload into rest controller:
Read request payload:
#Component
public class HttpLoggingFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(HttpLoggingFilter.class);
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ResettableStreamHttpServletRequest wrappedRequest = new ResettableStreamHttpServletRequest((HttpServletRequest) request);
wrappedRequest.getInputStream().read();
String body = IOUtils.toString(wrappedRequest.getReader());
System.out.println("!!!!!!!!!!!!!!!!!! " + body);
wrappedRequest.resetInputStream();
chain.doFilter(request, response);
}
public class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper {
private byte[] rawData;
private HttpServletRequest request;
private ResettableServletInputStream servletStream;
ResettableStreamHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
this.servletStream = new ResettableServletInputStream();
}
void resetInputStream() {
servletStream.stream = new ByteArrayInputStream(rawData);
}
#Override
public ServletInputStream getInputStream() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getInputStream());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return servletStream;
}
#Override
public BufferedReader getReader() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getInputStream());
servletStream.stream = new ByteArrayInputStream(rawData);
}
String encoding = getCharacterEncoding();
if (encoding != null) {
return new BufferedReader(new InputStreamReader(servletStream, encoding));
} else {
return new BufferedReader(new InputStreamReader(servletStream));
}
}
private class ResettableServletInputStream extends ServletInputStream {
private InputStream stream;
#Override
public int read() throws IOException {
return stream.read();
}
#Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setReadListener(ReadListener readListener) {
// TODO Auto-generated method stub
}
}
}
}
Rest endpoint:
#RestController()
public class HomeController {
#PostMapping(value = "/v1")
public Response handleMessage(#RequestBody Transaction transaction, HttpServletRequest request, org.zalando.logbook.HttpRequest requestv, HttpServletResponse response) throws Exception {
// Get here request and response and log it into DB
}
}
How I can call HttpLoggingFilter into the Java method handleMessage and get the request as body String? Probably I can make it service and Inject it? Can you give me some advice how I can assess the code?
Here are a bunch of classes to do it. This is a once a OncePerRequestFilter implementation, check here https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/OncePerRequestFilter.html. Basically the problem is that in the chain filter, the request stream and response stream can be read just once. So, need to wrap these 2 streams inside something that can be read more than once.
In the first 2 lines I wrapped request and response inside requestToUse and responseToUse. ResettableStreamHttpServletRequest and ResettableStreamHttpServletResponse are wrapper classes that keeps the original string body inside of them, and every time the stream is needed they return a new stream.Then from there, you forget about request and response and start using requestToUse and responseToUse.
I took this from an old project I did. Actually there are more clases, but I extracted the main parts for you. This may not compile right away. Give it a try and let me know and I will help you to make it work.
public class RequestResponseLoggingFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//here you wrap the request and response into some resetable istream class
HttpServletRequest requestToUse = new ResettableStreamHttpServletRequest(request);
HttpServletResponse responseToUse = new ResettableStreamHttpServletResponse(response);
//you read the request to log it
byte[] payload = IOUtils.toByteArray(requestToUse.getReader(), requestToUse.getCharacterEncoding());
String body = new String(payload, requestToUse.getCharacterEncoding());
//here you log the body request
log.(body);
//let the chain continue
filterChain.doFilter(requestToUse, responseToUse);
// Here we log the response
String response = new String(responseToUse.toString().getBytes(), responseToUse.getCharacterEncoding());
//since you can read the stream just once, you will need it again for chain to be able to continue, so you reset it
ResettableStreamHttpServletResponse responseWrapper = WebUtils.getNativeResponse(responseToUse, ResettableStreamHttpServletResponse.class);
if (responseWrapper != null) {
responseWrapper.copyBodyToResponse(true);
}
}
}
public class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper {
private byte[] rawData;
private ResettableServletInputStream servletStream;
public ResettableStreamHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
rawData = IOUtils.toByteArray(request.getInputStream());
servletStream = new ResettableServletInputStream();
servletStream.setStream(new ByteArrayInputStream(rawData));
}
#Override
public ServletInputStream getInputStream() throws IOException {
servletStream.setStream(new ByteArrayInputStream(rawData));
return servletStream;
}
#Override
public BufferedReader getReader() throws IOException {
servletStream.setStream(new ByteArrayInputStream(rawData));
return new BufferedReader(new InputStreamReader(servletStream));
}
}
public class ResettableStreamHttpServletResponse extends HttpServletResponseWrapper {
private ByteArrayServletOutputStream byteArrayServletOutputStream = new ByteArrayServletOutputStream();
public ResettableStreamHttpServletResponse(HttpServletResponse response) throws IOException {
super(response);
}
/**
* Copy the cached body content to the response.
*
* #param complete whether to set a corresponding content length for the complete cached body content
* #since 4.2
*/
public void copyBodyToResponse(boolean complete) throws IOException {
byte[] array = byteArrayServletOutputStream.toByteArray();
if (array.length > 0) {
HttpServletResponse rawResponse = (HttpServletResponse) getResponse();
if (complete && !rawResponse.isCommitted()) {
rawResponse.setContentLength(array.length);
}
rawResponse.getOutputStream().write(byteArrayServletOutputStream.toByteArray());
if (complete) {
super.flushBuffer();
}
}
}
/**
* The default behavior of this method is to return getOutputStream() on the wrapped response object.
*/
#Override
public ServletOutputStream getOutputStream() throws IOException {
return byteArrayServletOutputStream;
}
/**
* The default behavior of this method is to return getOutputStream() on the wrapped response object.
*/
#Override
public String toString() {
String response = new String(byteArrayServletOutputStream.toByteArray());
return response;
}
}
You dont need to do anything special here, Spring framework will do it for you.
All you need is:
Create a Pojo or Bean which represents your XML data.
Add xml data format dependency to Gradle/Maven which will bind the request xml to your pojo.
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.9.9'
Tell your request handler to accept XML like this:
#RequestMapping(value = "/xmlexample", method = RequestMethod.POST,consumes = "application/xml;charset=UTF-8")
public final boolean transactionHandler(#Valid #RequestBody Transaction transaction) {
log.debug("Received transaction request with data {}", transaction);
return true;
}
And voila, you will have your transaction bean populated with your XML data.
I have a method which returns a file object of an image:
public File getPhoto(entryId){...}
I call this method from my action method and set the file to a DTO File variable:
myDto.photo = getPhoto(entryId);
// where entryId refers to the name of the image file
// e.g. ent01 for ent01.gif, ent02 for ent02.gif and so on.
Now, in my JSP file I would like to display the image through a code like this:
<img src = "${myDto.photo}">
However,I realized that the myDto.photo is a file object thus has the absolute path of the file and not the URL needed for the img src in JSP.
Through searching, I understand that I can use a servlet and use something like
<img src = "${pageContext.request.contextPath}/image/ent01.gif"}.
However, I'm a little confused about this one as I wanted the filename part (ent01.gif) to vary based from the input entryId.
I hope anyone can shed light for me on this one. A lot of thanks.
You can Create a Controller Class for you to diplay the image you want.
#Controller
public class ImageReadFile{
// this is for mapping your image related path.
#RequestMapping(value="/image/*")
public void readImage(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sc = request.getServletContext();
//here i uploaded my image in this path
// You can set any path here
String imagePath = "/home/somefolder/Workspaces/Images/";
String [] fragmentFilename = request.getServletPath().split("/");
//Check if image isn't set
if(fragmentFilename.length <= 2){
return;
}
String filename = fragmentFilename[2];
String requestedImage = "/"+filename;
if(filename == null){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
File image = new File(imagePath, URLDecoder.decode(requestedImage, "UTF-8"));
if(!image.exists()){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
String contentType = sc.getMimeType(image.getName());
response.reset();
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(image.length()));
Files.copy(image.toPath(), response.getOutputStream());
}
}
Servlet Version.
try this.
#WebServlet("/image/*")
public class ImageWriter extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext sc = request.getServletContext();
//here i uploaded my image in this path
// You can set any path here
String imagePath = "/home/somefolder/Workspaces/Images/";
String [] fragmentFilename = request.getServletPath().split("/");
//Check if image isn't set
if(fragmentFilename.length <= 2){
return;
}
String filename = fragmentFilename[2];
String requestedImage = "/"+filename;
if(filename == null){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
File image = new File(imagePath, URLDecoder.decode(requestedImage, "UTF-8"));
if(!image.exists()){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
String contentType = sc.getMimeType(image.getName());
response.reset();
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(image.length()));
Files.copy(image.toPath(), response.getOutputStream());
}
}
this is how you gonna set display it in jsp,
<img alt="${imageFilename}" src="${pageContext.request.contextPath}/image/${imageFilename}">
Just pass the Filename to jsp then let the controller read it and display it.
hope this will help you.
I've been searching the net and stackoverflow for an example of somebody inserting content into the response using a servlet filter, but can only find examples of people capturing/compressing the output and/or changing the headers. My goal is to append a chunk of HTML just before the closing </body> of all HTML responses.
I'm working on a solution that extends the HttpServletResponseWrapper to use my own PrintWriter, then overriding the write methods thereon. Inside the write method I'm storing the last 7 characters to see if it's equal to the closing body tag, and then I write my HTML chunk plus the closing body tag, before continuing normal write operations for the rest of the document.
I feel that somebody must have solved this problem already, and probably more elegantly than I will. I'd appreciate any examples of how to use a servlet filter to insert content into a response.
UPDATED
Responding to a comment, I am also trying to implement the CharResponseWrapper from http://www.oracle.com/technetwork/java/filters-137243.html. Here is my code:
PrintWriter out = response.getWriter();
CharResponseWrapper wrappedResponse = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(wrappedRequest, wrappedResponse);
String s = wrappedResponse.toString();
if (wrappedResponse.getContentType().equals("text/html") &&
StringUtils.isNotBlank(s)) {
CharArrayWriter caw = new CharArrayWriter();
caw.write(s.substring(0, s.indexOf("</body>") - 1));
caw.write("WTF</body></html>");
response.setContentLength(caw.toString().length());
out.write(caw.toString());
}
else {
out.write(wrappedResponse.toString());
}
out.close();
I am also wrapping the request, but that code works and shouldn't affect the response.
The codebase I am using, calls the getOutputStream method, instead of getWriter when it processes the response, so the examples included in the other answer doesn't help. Here is a more complete answer that works with both the OutputStream and the PrintWriter, even erroring correctly, if the writer is accessed twice. This is derived from the great example, DUMP REQUEST AND RESPONSE USING JAVAX.SERVLET.FILTER.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class MyFilter implements Filter
{
private FilterConfig filterConfig = null;
private static class ByteArrayServletStream extends ServletOutputStream
{
ByteArrayOutputStream baos;
ByteArrayServletStream(ByteArrayOutputStream baos)
{
this.baos = baos;
}
public void write(int param) throws IOException
{
baos.write(param);
}
}
private static class ByteArrayPrintWriter
{
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PrintWriter pw = new PrintWriter(baos);
private ServletOutputStream sos = new ByteArrayServletStream(baos);
public PrintWriter getWriter()
{
return pw;
}
public ServletOutputStream getStream()
{
return sos;
}
byte[] toByteArray()
{
return baos.toByteArray();
}
}
public class CharResponseWrapper extends HttpServletResponseWrapper
{
private ByteArrayPrintWriter output;
private boolean usingWriter;
public CharResponseWrapper(HttpServletResponse response)
{
super(response);
usingWriter = false;
output = new ByteArrayPrintWriter();
}
public byte[] getByteArray()
{
return output.toByteArray();
}
#Override
public ServletOutputStream getOutputStream() throws IOException
{
// will error out, if in use
if (usingWriter) {
super.getOutputStream();
}
usingWriter = true;
return output.getStream();
}
#Override
public PrintWriter getWriter() throws IOException
{
// will error out, if in use
if (usingWriter) {
super.getWriter();
}
usingWriter = true;
return output.getWriter();
}
public String toString()
{
return output.toString();
}
}
public void init(FilterConfig filterConfig) throws ServletException
{
this.filterConfig = filterConfig;
}
public void destroy()
{
filterConfig = null;
}
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
CharResponseWrapper wrappedResponse = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrappedResponse);
byte[] bytes = wrappedResponse.getByteArray();
if (wrappedResponse.getContentType().contains("text/html")) {
String out = new String(bytes);
// DO YOUR REPLACEMENTS HERE
out = out.replace("</head>", "WTF</head>");
response.getOutputStream().write(out.getBytes());
}
else {
response.getOutputStream().write(bytes);
}
}
}
You will need to implement HttpServletResponseWrapper to modify the response. See this document The Essentials of Filters, it has an example that transforms the response, which is more than what you want
Edit
I have tried a simple Servlet with response filter and it worked perfectly. The Servlet output the string Test and the response filter append to it the string filtered and finally when I run from the browser I get the response Test filtered which is what you are trying to achieve.
I did run the below code on Apache Tomcat 7 and it is working without exceptions.
Servlet:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Test");
}
Filter:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("BEFORE filter");
PrintWriter out = response.getWriter();
CharResponseWrapper responseWrapper = new CharResponseWrapper(
(HttpServletResponse) response);
chain.doFilter(request, responseWrapper);
String servletResponse = new String(responseWrapper.toString());
out.write(servletResponse + " filtered"); // Here you can change the response
System.out.println("AFTER filter, original response: "
+ servletResponse);
}
CharResponseWrapper (exactly as the article)
public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response) {
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter() {
return new PrintWriter(output);
}
}
web.xml
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/TestServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/TestServlet/*</url-pattern>
</filter-mapping>
The iTech answer worked partially for me and this is based on that response..
But you must notice, that it seems some web servers (and AppEngine Standard) closes the outputStream after the first call to chain.doFilter inside a Filter..
So when you need to write on the pre-saved PrintWritter, the stream is closed and you get a blank screen. (I didn't recieve even an error to realise what was happening).
So the solution for me was creating a "dummy" ServletOutputStream and returning back in the getOutputStream method of my ResponseWrapper.
These changes plus the solution of iTech allowed me to insert a fully rendered jsp response in html inside a json response (properly escaping conflictive characters like quotes).
This is my code:
Myfilter
#WebFilter({"/json/*"})
public class Myfilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//Save original writer
PrintWriter out = response.getWriter();
//Generate a response wrapper with a different output stream
ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
//Process all in the chain (=get the jsp response..)
chain.doFilter(request, responseWrapper);
//Parse the response
out.write("BEFORE"+responseWrapper.toString()+"AFTER"); //Just + for clear display, better use a StringUtils.concat
}
#Override
public void destroy() {}
}
My ResponseWrapper:
public class ResponseWrapper extends HttpServletResponseWrapper {
private StringWriter output;
public String toString() {
return output.toString();
}
public ResponseWrapper(HttpServletResponse response) {
super(response);
//This creates a new writer to prevent the old one to be closed
output = new StringWriter();
}
public PrintWriter getWriter() {
return new PrintWriter(output,false);
}
#Override
public ServletOutputStream getOutputStream() throws IOException {
//This is the magic to prevent closing stream, create a "virtual" stream that does nothing..
return new ServletOutputStream() {
#Override
public void write(int b) throws IOException {}
#Override
public void setWriteListener(WriteListener writeListener) {}
#Override
public boolean isReady() {
return true;
}
};
}
}
Great! but please update content-length,
String out = new String(bytes);
// DO YOUR REPLACEMENTS HERE
out = out.replace("</head>", "WTF</head>");
response.setContentLength(out.length());
response.getOutputStream().write(out.getBytes());
I have next problem... when i submit form and my Post method end. Form(or not)throwing empty alert window. how can I delete this throwing window?
ClienSide
....
final FormPanel form = new FormPanel();
form.setAction(GWT.getModuleBaseURL()+"upload");
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
VerticalPanel panel = new VerticalPanel();
form.setWidget(panel);
FileUpload upload = new FileUpload();
upload.setName("uploadFormElement");
panel.add(upload);
fileButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
form.submit();
}
});
FileUploadServlet
public class FileUploadServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, resp);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (ServletFileUpload.isMultipartContent(req)) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(req);
for (FileItem fileItem : items) {
if (fileItem.isFormField()) continue;
String fileName = fileItem.getName();
if (fileName != null) {
fileName = FilenameUtils.getName(fileName);
}
File uploadedFile = new File("test.txt");
if (uploadedFile.createNewFile()) {
fileItem.write(uploadedFile);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Maybe someone knows the reason of this alert?
If it is a simple Javascript alert window you need to track/search for it in three places
Steps - Search for alert string across client code
1) In javascript - third party .js file . String search for `alert` in such js files
2) In third party gwt jar .
a) String search for Window.alert in the GWT java code
b) String search for wnd.alert in GWT jsni code
3) In Your own source code - repeat steps "a" and "b" from Step 2
It is unlikely but also string search you server side code base if in case they are building a string in response and displaying it via some other mechanism.
i'm study to devolop a servlet/filter to use in a web application, the filter have to record every request on the site by all user of the web application.
in my head the filter have to work in this way
filter -> request -> save request -> do.chain
public class ServletFilter implements Filter {
private Application fApp;
StringWriter ResponseRECORDER;
StringWriter RequestRECORDER;
#Override
public void init(FilterConfig config) throws ServletException {
fApp = (Application)config.getServletContext().getAttribute("application");
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request,response);
// Ignore non-http requests.
if (!(request instanceof HttpServletRequest))
{
chain.doFilter(request,response);
return;
}
((HttpServletRequest)request).getSession();
// Write the request out to the recording file.
recordReqResHTTP((HttpServletRequest) request,
(HttpServletResponse) response);
StringBuilder Fixed = new StringBuilder();
Fixed.append("[Message]");
Fixed.append("[time]");
Fixed.append(System.currentTimeMillis());
Fixed.append("[/time]");
Fixed.append("[Request]");
Fixed.append(RequestRECORDER);
Fixed.append("[/Request]");
Fixed.append("[Response]");
Fixed.append(ResponseRECORDER);
Fixed.append("[/Response]");
Fixed.append("[/Message]");
MessagingService s = (MessagingService)fApp
.getService("it.interprise.core.workflow.MessagingService");
try {
s.send("recorder", Fixed.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void destroy() {
}
public void recordReqResHTTP(HttpServletRequest request,
HttpServletResponse response)
{
//HttpSession session = request.getSession();
//costruisco una stringa per la raccolta dati
StringWriter ResponseRECORDER = new StringWriter();
StringWriter RequestRECORDER = new StringWriter();
try
{
//Registro la Request
PrintWriter out = new PrintWriter(RequestRECORDER);
out.println("<request>");
out.print("<uri>");
out.print(request.getRequestURI());
out.println("</uri>");
Enumeration e = request.getParameterNames();
while (e.hasMoreElements())
{
String paramName = (String) e.nextElement();
String[] values = request.getParameterValues(paramName);
for (int i=0; i < values.length; i++)
{
out.print("<param><name>");
out.print(paramName);
out.print("</name><value>");
out.print(values[i]);
out.println("</value></param>");
}
}
out.println("</request>");
out.close();
//Registro la Response
PrintWriter res = new PrintWriter(ResponseRECORDER);
res.println("<request>");
res.print("<uri>");
res.print(request.getRequestURI());
res.println("</uri>");
Enumeration f = request.getParameterNames();
while (f.hasMoreElements())
{
String paramName = (String) f.nextElement();
String[] values = request.getParameterValues(paramName);
for (int i=0; i < values.length; i++)
{
res.print("<param><name>");
res.print(paramName);
res.print("</name><value>");
res.print(values[i]);
res.println("</value></param>");
}
}
out.println("</request>");
out.close();
}
catch (Exception exc)
{
}
}
}
and the same for the response, have you any idea how i could solve the problem?
With this filter the web application stop response...
thank you
The first thing you should do is to log the Exception at the bottom of your example, at least. Maybe there is an Exception raised that cannot be identified by inspecting the code.
A few lines before you close the PrintWriter twice, which could lead to IOException.
Second: You declare instance variables ResponseRECORDER and RequestRECORDER, but later you declare two local variables with same name. Remove the instance variables - the filter must be implemented thread safe.
Once done, I'll guess we will see a hidden NullPointer.