i have a requirement in my project. i want to change the value of sended data through postman, like as if there is three parameter like as id, name, salary.now i am sending the data through postman
}
"id":1,
"name":"dhiraj",
"salary":787878
}
now when send the data,it should be save as actual data in database .but if i am sending like as that
}
"id":2,
"name":"",
"salary":787878
}
then name column should be null instead of empty in database.i am using following code for that, but not getting exact output,please help me .
'package com.httpmodify.test.HttpModify.filter;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Locale;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.LocaleResolver;
import com.httpmodify.test.HttpModify.model.Student;
#Component
public class RequestModify implements Filter{
private static Logger log=LoggerFactory.getLogger(Student.class);
private static final String ACCEPT_LANGUAGE = "Accept-Language";
#Autowired
LocaleResolver localeResolver;
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// Need to add code if something is required to be initialized.
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
StringBuilder requestJson = new StringBuilder();
String responseJson = "";
BufferedReader bufferedReader = request.getReader();
String line = null;
if (bufferedReader != null) {
while (null != (line = bufferedReader.readLine())) {
requestJson.append(line);
}
}
if (request.getMethod().equals("POST")) {
RestAPIRequestWrapper requestWrapper = new RestAPIRequestWrapper(request,
requestJson.toString().getBytes());
RestAPIResponseWrapper responseWrapper = new RestAPIResponseWrapper(response);
chain.doFilter(requestWrapper, responseWrapper);
response.setContentType("text/plain");
responseJson = responseWrapper.getCaptureAsString();
response.getWriter().write(responseWrapper.getCaptureAsString());
} else {
chain.doFilter(request, response);
}
}
#Override
public void destroy() {
// Need to write some code if some resource needs to be destroyed.
}
/**
* #param locale
* #return String
*/
private String getAcceptLanguage(String locale) {
return locale != null ? locale : "en";
}
}
'
package com.httpmodify.test.HttpModify.filter;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* #author Ashwini Upadhyay
* #Version 1.0
* #date 2019-Apr-02 12:57:38 PM
*/
public class RestAPIRequestWrapper extends HttpServletRequestWrapper {
private final ByteArrayInputStream decryptedDataBAIS;
private HttpServletRequest wrapped;
private Map<String, String[]> parameterMap;
private Map<String, String> headerMap = new HashMap<>();
public RestAPIRequestWrapper(HttpServletRequest wrapped, byte[] decryptedData) {
super(wrapped);
this.wrapped = wrapped;
decryptedDataBAIS = new ByteArrayInputStream(decryptedData);
}
public RestAPIRequestWrapper(HttpServletRequest wrapped, byte[] decryptedData, Map<String, String> headerMap) {
super(wrapped);
this.wrapped = wrapped;
decryptedDataBAIS = new ByteArrayInputStream(decryptedData);
this.headerMap = headerMap;
}
public RestAPIRequestWrapper(HttpServletRequest wrapped) {
super(wrapped);
this.wrapped = wrapped;
decryptedDataBAIS = new ByteArrayInputStream("".getBytes());
}
public RestAPIRequestWrapper(HttpServletRequest wrapped, String paramstr) {
super(wrapped);
this.wrapped = wrapped;
decryptedDataBAIS = null;
String[] paramsArr = paramstr.split("&");
for (int i = 0; i < paramsArr.length; i++) {
String[] paramArr = paramsArr[i].split("=");
addParameter(paramArr[0], paramArr[1]);
}
}
#Override
public String getContentType() {
return super.getContentType();
}
#Override
public BufferedReader getReader() throws UnsupportedEncodingException {
return new BufferedReader(new InputStreamReader(decryptedDataBAIS, "UTF_8"));
}
#Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStream() {
#Override
public int read() {
return decryptedDataBAIS.read();
}
#Override
public boolean isFinished() {
return decryptedDataBAIS.available() == 0;
}
#Override
public boolean isReady() {
return true;
}
#Override
public void setReadListener(ReadListener arg0) {
throw new RuntimeException("Not implemented");
}
};
}
#Override
public Enumeration<String> getParameterNames() {
if (parameterMap == null) {
return wrapped.getParameterNames();
}
return Collections.enumeration(parameterMap.keySet());
}
#Override
public String[] getParameterValues(String name) {
if (parameterMap == null) {
return wrapped.getParameterValues(name);
}
return parameterMap.get(name);
}
#Override
public String getParameter(String name) {
if (parameterMap == null) {
return wrapped.getParameter(name);
}
String[] strings = parameterMap.get(name);
if (strings != null) {
return strings[0];
}
return null;
}
public void addParameter(String name, String value) {
if (parameterMap == null) {
parameterMap = new HashMap<>();
parameterMap.putAll(wrapped.getParameterMap());
}
String[] values = parameterMap.get(name);
if (values == null) {
values = new String[0];
}
List<String> list = new ArrayList<>(values.length + 1);
list.addAll(Arrays.asList(values));
list.add(value);
parameterMap.put(name, list.toArray(new String[0]));
}
#Override
public Map<String, String[]> getParameterMap() {
if (parameterMap == null) {
return wrapped.getParameterMap();
}
return Collections.unmodifiableMap(parameterMap);
}
#Override
public String getHeader(String headerName) {
String headerValue = null;
if (headerMap.containsKey(headerName)) {
headerValue = headerMap.get(headerName);
} else {
headerValue = super.getHeader(headerName);
}
return headerValue;
}
#Override
public Enumeration<String> getHeaders(String name) {
Set<String> values = new HashSet<>();
if (headerMap.containsKey(name) || name.equalsIgnoreCase("Authorization")) {
if (headerMap.get(name) != null)
values.add(headerMap.get(name));
} else {
for (Enumeration<String> e = super.getHeaders(name); e.hasMoreElements();) {
String headerValue = e.nextElement();
values.add(headerValue);
}
}
return Collections.enumeration(values);
}
#Override
public Enumeration<String> getHeaderNames() {
Set<String> names = new HashSet<>();
for (String name : headerMap.keySet()) {
names.add(name);
}
for (Enumeration<String> e = super.getHeaderNames(); e.hasMoreElements();) {
String headerName = e.nextElement();
if (!headerName.equalsIgnoreCase("Authorization"))
names.add(headerName);
}
return Collections.enumeration(names);
}
public void addHeader(String name, String value) {
headerMap.put(name, value);
}
}
package com.httpmodify.test.HttpModify.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* #author Ashwini Upadhyay
* #Version 1.0
* #date 2019-Apr-02 12:57:17 PM
*/
public class RestAPIResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream capture;
private ServletOutputStream output;
private PrintWriter writer;
public RestAPIResponseWrapper(HttpServletResponse response) {
super(response);
capture = new ByteArrayOutputStream(response.getBufferSize());
}
#Override
public ServletOutputStream getOutputStream() throws IOException {
if (writer != null) {
throw new IllegalStateException("getWriter() has already been called on this response.");
}
if (output == null) {
output = new ServletOutputStream() {
#Override
public void write(int b) throws IOException {
capture.write(b);
}
#Override
public void flush() throws IOException {
capture.flush();
}
#Override
public void close() throws IOException {
capture.close();
}
#Override
public boolean isReady() {
return false;
}
#Override
public void setWriteListener(WriteListener arg0) {
}
};
}
return output;
}
#Override
public PrintWriter getWriter() throws IOException {
if (output != null) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(capture, getCharacterEncoding()));
}
return writer;
}
#Override
public void flushBuffer() throws IOException {
super.flushBuffer();
if (writer != null) {
writer.flush();
} else if (output != null) {
output.flush();
}
}
public byte[] getCaptureAsBytes() throws IOException {
if (writer != null) {
writer.close();
} else if (output != null) {
output.close();
}
return capture.toByteArray();
}
public String getCaptureAsString() throws IOException {
return new String(getCaptureAsBytes(), getCharacterEncoding());
}
}
After getting the request in the controller, you can validate the input value. If the input for the name is empty then make it null, and perform the same operation for other input values. After performing these operations save the object to the database.
Related
I'm trying to write an Http Server using Apache Mina.
According to Mina's architecture, there should be 2 filters for this task, one for Http Request Passing and another for processing the request and generating the response. So using the Mina example codes, I came up with the following code, that has an acceptor, logging filter, Http filter, and a filter for processing request.
Initiation of the server runs correctly, but the request does not come to DummyHttpSever filter. I tried to debug, but could not find the issue. What is going wrong here?
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.api.AbstractIoFilter;
import org.apache.mina.api.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filterchain.ReadFilterChainController;
import org.apache.mina.http.DateUtil;
import org.apache.mina.http.HttpDecoderState;
import org.apache.mina.http.HttpServerDecoder;
import org.apache.mina.http.HttpServerEncoder;
import org.apache.mina.http.api.DefaultHttpResponse;
import org.apache.mina.http.api.HttpContentChunk;
import org.apache.mina.http.api.HttpEndOfContent;
import org.apache.mina.http.api.HttpMethod;
import org.apache.mina.http.api.HttpPdu;
import org.apache.mina.http.api.HttpRequest;
import org.apache.mina.http.api.HttpStatus;
import org.apache.mina.http.api.HttpVersion;
import org.apache.mina.transport.nio.NioTcpServer;
public class HttpTest {
public static void main(String[] args) throws Exception {
NioTcpServer httpServer = new NioTcpServer();
httpServer.setReuseAddress(true);
httpServer.setFilters(new ProtocolCodecFilter<HttpPdu, ByteBuffer, Void, HttpDecoderState>(new HttpServerEncoder(),
new HttpServerDecoder()), new LoggingFilter("DECODED"), new DummyHttpSever());
httpServer.getSessionConfig().setTcpNoDelay(true);
httpServer.bind(new InetSocketAddress(8080));
// run for 20 seconds
Thread.sleep(2000000000);
httpServer.unbind();
}
private static class DummyHttpSever extends AbstractIoFilter {
private HttpRequest incomingRequest;
private List<ByteBuffer> body;
#Override
public void messageReceived(IoSession session, Object message, ReadFilterChainController controller) {
if (message instanceof HttpRequest) {
System.out.println("This shit is working");
incomingRequest = (HttpRequest) message;
body = new ArrayList<ByteBuffer>();
// check if this request is going to be followed by and HTTP body or not
if (incomingRequest.getMethod() != HttpMethod.POST && incomingRequest.getMethod() != HttpMethod.PUT) {
sendResponse(session, incomingRequest);
} else {
}
} else if (message instanceof ByteBuffer) {
body.add((ByteBuffer) message);
} else if (message instanceof HttpEndOfContent) {
// we received all the post content, send the crap back
sendResponse(session, incomingRequest);
}
}
public void sendResponse(IoSession session, HttpRequest request) {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Server", "Apache MINA Dummy test server/0.0.");
headers.put("Date", DateUtil.getCurrentAsString());
headers.put("Connection", "Close");
String strContent = "Hello ! we reply to request !";
ByteBuffer content = ByteBuffer.wrap(strContent.getBytes());
// compute content len
headers.put("Content-Length", String.valueOf(content.remaining()));
session.write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SUCCESS_OK, headers));
session.write(new HttpContentChunk(content));
session.write(new HttpEndOfContent());
session.close(false);
}
}
}
Also, following are dependencies I am using.
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-http</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-coap</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>LATEST</version>
</dependency>
This is a simple Http web server, which you can modify according to your need. This example is a modification to the example lightweight component of Apache Mina examples.
Main.java
import java.net.InetSocketAddress;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.asyncweb.common.codec.HttpCodecFactory;
import org.apache.asyncweb.examples.lightweight.HttpProtocolHandler;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class Main {
public static void main(String[] args) throws Exception {
SocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new HttpCodecFactory()));
acceptor.setReuseAddress(true);
acceptor.getSessionConfig().setReuseAddress(true);
acceptor.getSessionConfig().setReceiveBufferSize(1024);
acceptor.getSessionConfig().setSendBufferSize(1024);
acceptor.getSessionConfig().setTcpNoDelay(true);
acceptor.getSessionConfig().setSoLinger(-1);
acceptor.setBacklog(10240);
acceptor.setHandler(new HttpProtocolHandler());
acceptor.bind(new InetSocketAddress(9012));
}
}
HttpProtocalHandler.java
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.future.WriteFuture;
import org.apache.asyncweb.common.HttpRequest;
import org.apache.asyncweb.common.HttpResponseStatus;
import org.apache.asyncweb.common.MutableHttpResponse;
import org.apache.asyncweb.common.DefaultHttpResponse;
import org.apache.asyncweb.common.HttpHeaderConstants;
public class HttpProtocolHandler implements IoHandler {
private static final int CONTENT_PADDING = 0; // 101
private final Map<Integer, IoBuffer> buffers = new ConcurrentHashMap<Integer, IoBuffer>();
private final Timer timer;
public HttpProtocolHandler() {
timer = new Timer(true);
}
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
if (!(cause instanceof IOException)) {
cause.printStackTrace();
}
session.close();
}
public Dictionary extractParameters(Map hashParameters){
Dictionary parameters = new Hashtable();
Iterator it = hashParameters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
parameters.put(pair.getKey(), ((ArrayList) pair.getValue()).get(0) );
// it.remove(); // avoids a ConcurrentModificationException
}
return parameters;
}
public void messageReceived(IoSession session, Object message)
throws Exception {
HttpRequest req = (HttpRequest) message;
String path = req.getRequestUri().getPath(); //path: /echo
String end_point = path;
Dictionary parameters = this.extractParameters(req.getParameters());
String response = "";
/* switch (end_point) {
case "/io":
response= new IOHandler().handleRequest(parameters);
break;
case "/cpu":
response= new CPUHandler().handleRequest(parameters);
break;
case "/db":
response= new DBHandler().handleRequest(parameters);
break;
case "/memory":
response= new MemoryHandler().handleRequest(parameters);
break;
default:
response = "No end point found";
} */
response = "No end point found";
MutableHttpResponse res;
// if (path.startsWith("/size/")) {
// doDataResponse(session, req);
// } else if (path.startsWith("/delay/")) {
// doAsynchronousDelayedResponse(session, req);
// } else if (path.startsWith("/adelay/")) {
// doAsynchronousDelayedResponse(session, req);
// } else {
res = new DefaultHttpResponse();
IoBuffer bb = IoBuffer.allocate(1024);
bb.setAutoExpand(true);
bb.putString(response.toString(), Charset.forName("UTF-8").newEncoder());
bb.flip();
res.setContent(bb);
// res.setHeader("Pragma", "no-cache");
// res.setHeader("Cache-Control", "no-cache");
res.setStatus(HttpResponseStatus.OK);
WriteFuture future = session.write(res);
if (!HttpHeaderConstants.VALUE_KEEP_ALIVE.equalsIgnoreCase(
res.getHeader( HttpHeaderConstants.KEY_CONNECTION))) {
future.addListener(IoFutureListener.CLOSE);
}
}
private void writeResponse(IoSession session, HttpRequest req,
MutableHttpResponse res) {
res.normalize(req);
WriteFuture future = session.write(res);
if (!HttpHeaderConstants.VALUE_KEEP_ALIVE.equalsIgnoreCase(
res.getHeader( HttpHeaderConstants.KEY_CONNECTION))) {
future.addListener(IoFutureListener.CLOSE);
}
}
private void doDataResponse(IoSession session, HttpRequest req) {
String path = req.getRequestUri().getPath();
int size = Integer.parseInt(path.substring(path.lastIndexOf('/') + 1))
+ CONTENT_PADDING;
MutableHttpResponse res = new DefaultHttpResponse();
res.setStatus(HttpResponseStatus.OK);
res.setHeader("ETag", "W/\"" + size + "-1164091960000\"");
res.setHeader("Last-Modified", "Tue, 31 Nov 2006 06:52:40 GMT");
IoBuffer buf = buffers.get(size);
if (buf == null) {
buf = IoBuffer.allocate(size);
buffers.put(size, buf);
}
res.setContent(buf.duplicate());
writeResponse(session, req, res);
}
private void doAsynchronousDelayedResponse(final IoSession session,
final HttpRequest req) {
String path = req.getRequestUri().getPath();
int delay = Integer.parseInt(path.substring(path.lastIndexOf('/') + 1));
final MutableHttpResponse res = new DefaultHttpResponse();
res.setStatus(HttpResponseStatus.OK);
res.setHeader("ETag", "W/\"0-1164091960000\"");
res.setHeader("Last-Modified", "Tue, 31 Nov 2006 06:52:40 GMT");
timer.schedule(new TimerTask() {
#Override
public void run() {
writeResponse(session, req, res);
}
}, delay);
}
public void messageSent(IoSession session, Object message) throws Exception {
}
public void sessionClosed(IoSession session) throws Exception {
}
public void sessionCreated(IoSession session) throws Exception {
}
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
session.close();
}
public void sessionOpened(IoSession session) throws Exception {
session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
}
}
In my case, I have Java 1.6 and want to connect to a remote server which only supports TLS1.2. Server URL is: https://blagajne-test.fu.gov.si:9002 and certificate public key is here: http://datoteke.durs.gov.si/dpr/files/test-tls.cer
I have no possibility to upgrade Java because is a part of Oracle Database 11g (11.4).
I tried to write a simple program in Java which uses BouncyCastel libraries but got error: Exception in thread "main"
org.bouncycastle.crypto.tls.TlsFatalAlertReceived: handshake_failure(40)
at org.bouncycastle.crypto.tls.TlsProtocol.handleAlertMessage(Unknown Source)
The step I have followed was:
1.) have downloaded test-tls.cer and imported the key into jssacerts and cacerts.
2.) In Java have done this example:
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.URL;
import java.security.MessageDigest;
import java.security.Security;
import java.security.Signature;
import javax.net.ssl.HttpsURLConnection;
import org.bouncycastle.crypto.tls.CertificateRequest;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsCredentials;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Test3 {
public static Signature podpis = null;
public static MessageDigest md = null;
static {
try {
Security.addProvider(new BouncyCastleProvider());
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
String httpsURL = "https://blagajne-test.fu.gov.si:9002";
URL myurl = new URL(httpsURL);
HttpsURLConnection con = (HttpsURLConnection )myurl.openConnection();
con.setSSLSocketFactory(new TLSSocketConnectionFactory());
InputStream ins = con.getInputStream();
}
}
and
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.security.cert.X509Certificate;
import org.apache.commons.logging.Log;
import org.bouncycastle.crypto.tls.Certificate;
import org.bouncycastle.crypto.tls.CertificateRequest;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.ExtensionType;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsCredentials;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class TLSSocketConnectionFactory extends SSLSocketFactory {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Adding Custom BouncyCastleProvider
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SECURE RANDOM
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
private SecureRandom _secureRandom = new SecureRandom();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Adding Custom BouncyCastleProvider
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
public Socket createSocket(Socket socket, final String host, int port, boolean arg3)
throws IOException {
if (socket == null) {
socket = new Socket();
}
if (!socket.isConnected()) {
socket.connect(new InetSocketAddress(host, port));
}
final TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), _secureRandom);
return _createSSLSocket(host, tlsClientProtocol);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SOCKET FACTORY METHODS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
public String[] getDefaultCipherSuites() {
return null;
}
#Override
public String[] getSupportedCipherSuites() {
return null;
}
#Override
public Socket createSocket(String host,
int port) throws IOException, UnknownHostException {
return null;
}
#Override
public Socket createSocket(InetAddress host,
int port) throws IOException {
return null;
}
#Override
public Socket createSocket(String host,
int port,
InetAddress localHost,
int localPort) throws IOException, UnknownHostException {
return null;
}
#Override
public Socket createSocket(InetAddress address,
int port,
InetAddress localAddress,
int localPort) throws IOException {
return null;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SOCKET CREATION
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private SSLSocket _createSSLSocket(final String host, final TlsClientProtocol tlsClientProtocol) {
return new SSLSocket() {
private java.security.cert.Certificate[] peertCerts;
#Override
public InputStream getInputStream() throws IOException {
return tlsClientProtocol.getInputStream();
}
#Override
public OutputStream getOutputStream() throws IOException {
return tlsClientProtocol.getOutputStream();
}
#Override
public synchronized void close() throws IOException {
tlsClientProtocol.close();
}
#Override
public void addHandshakeCompletedListener(HandshakeCompletedListener arg0) {
}
#Override
public boolean getEnableSessionCreation() {
return false;
}
#Override
public String[] getEnabledCipherSuites() {
return null;
}
#Override
public String[] getEnabledProtocols() {
return null;
}
#Override
public boolean getNeedClientAuth() {
return false;
}
#Override
public SSLSession getSession() {
return new SSLSession() {
#Override
public int getApplicationBufferSize() {
return 0;
}
#Override
public String getCipherSuite() {
throw new UnsupportedOperationException();
}
#Override
public long getCreationTime() {
throw new UnsupportedOperationException();
}
#Override
public byte[] getId() {
throw new UnsupportedOperationException();
}
#Override
public long getLastAccessedTime() {
throw new UnsupportedOperationException();
}
#Override
public java.security.cert.Certificate[] getLocalCertificates() {
throw new UnsupportedOperationException();
}
#Override
public Principal getLocalPrincipal() {
throw new UnsupportedOperationException();
}
#Override
public int getPacketBufferSize() {
throw new UnsupportedOperationException();
}
#Override
public X509Certificate[] getPeerCertificateChain()
throws SSLPeerUnverifiedException {
return null;
}
#Override
public java.security.cert.Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
return peertCerts;
}
#Override
public String getPeerHost() {
throw new UnsupportedOperationException();
}
#Override
public int getPeerPort() {
return 0;
}
#Override
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
return null;
//throw new UnsupportedOperationException();
}
#Override
public String getProtocol() {
throw new UnsupportedOperationException();
}
#Override
public SSLSessionContext getSessionContext() {
throw new UnsupportedOperationException();
}
#Override
public Object getValue(String arg0) {
throw new UnsupportedOperationException();
}
#Override
public String[] getValueNames() {
throw new UnsupportedOperationException();
}
#Override
public void invalidate() {
throw new UnsupportedOperationException();
}
#Override
public boolean isValid() {
throw new UnsupportedOperationException();
}
#Override
public void putValue(String arg0, Object arg1) {
throw new UnsupportedOperationException();
}
#Override
public void removeValue(String arg0) {
throw new UnsupportedOperationException();
}
};
}
#Override
public String[] getSupportedProtocols() {
return null;
}
#Override
public boolean getUseClientMode() {
return false;
}
#Override
public boolean getWantClientAuth() {
return false;
}
#Override
public void removeHandshakeCompletedListener(HandshakeCompletedListener arg0) {
}
#Override
public void setEnableSessionCreation(boolean arg0) {
}
#Override
public void setEnabledCipherSuites(String[] arg0) {
}
#Override
public void setEnabledProtocols(String[] arg0) {
}
#Override
public void setNeedClientAuth(boolean arg0) {
}
#Override
public void setUseClientMode(boolean arg0) {
}
#Override
public void setWantClientAuth(boolean arg0) {
}
#Override
public String[] getSupportedCipherSuites() {
return null;
}
#Override
public void startHandshake() throws IOException {
tlsClientProtocol.connect(new DefaultTlsClient() {
#SuppressWarnings("unchecked")
#Override
public Hashtable<Integer, byte[]> getClientExtensions() throws IOException {
Hashtable<Integer, byte[]> clientExtensions = super.getClientExtensions();
if (clientExtensions == null) {
clientExtensions = new Hashtable<Integer, byte[]>();
}
//Add host_name
byte[] host_name = host.getBytes();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final DataOutputStream dos = new DataOutputStream(baos);
dos.writeShort(host_name.length + 3);
dos.writeByte(0); //
dos.writeShort(host_name.length);
dos.write(host_name);
dos.close();
clientExtensions.put(ExtensionType.server_name, baos.toByteArray());
return clientExtensions;
}
#Override
public TlsAuthentication getAuthentication()
throws IOException {
return new TlsAuthentication() {
#Override
public void notifyServerCertificate(Certificate serverCertificate) throws IOException {
try {
KeyStore ks = _loadKeyStore();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<java.security.cert.Certificate> certs = new LinkedList<java.security.cert.Certificate>();
boolean trustedCertificate = false;
for (org.bouncycastle.asn1.x509.Certificate c : serverCertificate.getCertificateList()) {
java.security.cert.Certificate cert = cf.generateCertificate(new ByteArrayInputStream(c.getEncoded()));
certs.add(cert);
String alias = ks.getCertificateAlias(cert);
if (alias != null) {
if (cert instanceof java.security.cert.X509Certificate) {
try {
((java.security.cert.X509Certificate) cert).checkValidity();
trustedCertificate = true;
} catch (CertificateExpiredException cee) {
cee.printStackTrace();
}
}
} else {
System.out.println("-->");
}
}
if (!trustedCertificate) {
throw new CertificateException("Unknown cert " + serverCertificate);
}
peertCerts = certs.toArray(new java.security.cert.Certificate[0]);
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException(ex);
}
}
#Override
public TlsCredentials getClientCredentials(CertificateRequest arg0)
throws IOException {
return null;
}
/**
* Private method to load keyStore with system or
* default properties.
*
* #return
* #throws Exception
*/
private KeyStore _loadKeyStore() throws Exception {
FileInputStream trustStoreFis = null;
try {
String sysTrustStore = null;
File trustStoreFile = null;
KeyStore localKeyStore = null;
sysTrustStore = System.getProperty("javax.net.ssl.trustStore");
String javaHome;
if (!"NONE".equals(sysTrustStore)) {
if (sysTrustStore != null) {
trustStoreFile = new File(sysTrustStore);
trustStoreFis = _getFileInputStream(trustStoreFile);
} else {
javaHome = System.getProperty("java.home");
trustStoreFile = new File(javaHome + File.separator + "lib" + File.separator + "security" + File.separator + "jssecacerts");
if ((trustStoreFis = _getFileInputStream(trustStoreFile)) == null) {
trustStoreFile = new File(javaHome + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts");
trustStoreFis = _getFileInputStream(trustStoreFile);
}
}
if (trustStoreFis != null) {
sysTrustStore = trustStoreFile.getPath();
} else {
sysTrustStore = "No File Available, using empty keystore.";
}
}
System.out.println("sysTrustStore: " +sysTrustStore);
String trustStoreType = System.getProperty("javax.net.ssl.trustStoreType") != null ? System.getProperty("javax.net.ssl.trustStoreType") : KeyStore.getDefaultType();
String trustStoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider") != null ? System.getProperty("javax.net.ssl.trustStoreProvider") : "";
if (trustStoreType.length() != 0) {
if (trustStoreProvider.length() == 0) {
localKeyStore = KeyStore.getInstance(trustStoreType);
} else {
localKeyStore = KeyStore.getInstance(trustStoreType, trustStoreProvider);
}
char[] keyStorePass = null;
String str5 = System.getProperty("javax.net.ssl.trustStorePassword") != null ? System.getProperty("javax.net.ssl.trustStorePassword") : "";
if (str5.length() != 0) {
keyStorePass = str5.toCharArray();
}
localKeyStore.load(trustStoreFis, (char[]) keyStorePass);
if (keyStorePass != null) {
for (int i = 0; i < keyStorePass.length; i++) {
keyStorePass[i] = 0;
}
}
}
return (KeyStore) localKeyStore;
} finally {
if (trustStoreFis != null) {
trustStoreFis.close();
}
}
}
private FileInputStream _getFileInputStream(File paramFile) throws Exception {
if (paramFile.exists()) {
return new FileInputStream(paramFile);
}
return null;
}
};
}
});
}
};//Socket
}
}
When I execute the main program I got:
What I'm doing wrong or why I get back that exception?
Download jce_policy-6.zip from oracle website
unzip the jce_policy-6.zip you will have two jars local_policy.jar and US_export_policy.jar.
Install the jars based on the README file provided in the zip - two jars should be copied to %JAVA_HOME%/lib/security
Edit the file %JAVA_HOME%/jre/lib/security/java.security and locate the security-provider list add this line -
security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
Use the following code to get the SSLContext.
Provider provider = new BouncyCastleJsseProvider();
Security.addProvider(provider);
SSLContext ctx = SSLContext.getInstance("TLS",provider.getName());
Please switch to Version 1.55 this will fix the issue...
I was given code that I have to make do something else. When I go to compile my servlet, it doesn't recognize my bean. I've deleted, recompiled, and tried from all different directories. I have no clue why this isn't working.
import BH.*;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.util.function.*;
import static java.util.Arrays.asList;
import java.text.DateFormat;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;
public class sessionServlet extends HttpServlet {
private List<String[]> the_sessions;
private DateFormat df;
public static ReentrantLock thelock = new ReentrantLock();
public void init() throws ServletException {
the_sessions=new ArrayList<String[]>();
df=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
if ((!(req.getParameter("task")==null))&&(req.getParameter("task").trim().equals("deploy"))) {
PrintWriter out = res.getWriter();
out.println("<html>");
out.println("<body>");
out.println("<hr /><center><h1>sessionServlet Deployed</h1></center><hr />");
out.println("</body>");
out.println("</html>");
return;
}
Consumer <String> forwardTo =(s) ->ForwardTo(s,req,res);
boolean is_first_visit=true;
String[] this_session=new String[3];
String manager = req.getParameter("manager");
for (String [] a_session :the_sessions) {
if (a_session[0].equals(manager)) { //Found an active session
is_first_visit=false;
this_session=a_session;
break;
}
}
if ((req.getParameter("task")==null)&&(!is_first_visit)) {
the_sessions.remove(this_session);
is_first_visit=true; // just used http://hoare.cs.umsl.edu/servlet/js_test/sessionServlet
}
req.setAttribute("thesessioncount",the_sessions.size());
if (is_first_visit) {
if (the_sessions.size()==10) {
forwardTo.accept("noSessions.jsp"); //No Available Sessions
return;
}
String randomStr = getRandomString();
String[] new_session = {randomStr,df.format(new Date()),"need a name"};
the_sessions.add(new_session);
this_session=new_session;
req.setAttribute("manager",randomStr);
forwardTo.accept("startSession.jsp");
return;
}
String the_name="";
String the_pw="";
if (this_session[2].equals("need a name")) { //No name given yet
the_name=req.getParameter("whoisit");
the_pw=req.getParameter("passwd");
if ((the_name==null)||(the_name.trim().length()==0)||checkPW(the_name,the_pw)) { //checkPW returns false if correct
the_sessions.remove(this_session);
req.setAttribute("thesessioncount",the_sessions.size());
forwardTo.accept("startSession.jsp");
return; // didn't enter a name in startSession
}
}
this_session[2]=the_name.trim();
req.setAttribute("thename", this_session[2]);
if (tooLong(this_session[1],df.format(new Date()))) { //Has the session timed out?
the_sessions.remove(this_session);
forwardTo.accept("Expired.jsp");
return;
} else {
this_session[1]=df.format(new Date()); //reset the last session activity time
NotesBean thesenotes=new NotesBean();
if(req.getParameter("task").trim().equals("9")){
the_sessions.remove(this_session);
forwardTo.accept("exit.jsp");
return;
}
thelock.lock();
if (!req.getParameter("task").trim().equals("0")) { //add ACC here, also show/update posts
thesenotes.setAll(req.getParameter("java_source"),Integer.parseInt(req.getParameter("version")));
if (req.getParameter("task").trim().equals("2")) {
thesenotes.setNotes(req.getParameter("notes"),req.getParameter("java_source"),Integer.parseInt(req.getParameter("version")));
}
}
req.setAttribute("thesessioncount",the_sessions.size());
req.setAttribute("theBean",thesenotes);
req.setAttribute("manager",manager);
//req.setAttribute("theURL", "http://www.umsl.edu/~siegelj/turing.jpg");
forwardTo.accept("getNotes.jsp");
thelock.unlock();
return;
}
}//end doGet
boolean tooLong(String now,String then){
//Check amount of time that passed
return false;
}
boolean checkPW(String name,String password){
AccountBean theAccount = new AccountBean();
theAccount.setAccount(name);
if(theAccount.isPassword(password))
return false;
return true;
}
public void log(String s){
FileWriter fileWriter = null;
try {
String content =s+" at :"+new Date(System.currentTimeMillis()).toString()+"\n";
File theLogFile = new File("C:/Tomcat/webapps/js_test/session.log");
fileWriter = new FileWriter(theLogFile,true);
fileWriter.write(content);
} catch (IOException ex) {
} finally {
try {
fileWriter.close();
} catch (IOException ex) {
}
}
}
void ForwardTo(String s,HttpServletRequest req, HttpServletResponse res)
{
RequestDispatcher rd= req.getRequestDispatcher(s);
try {
rd.forward(req, res);
} catch (IOException|ServletException is) {
log(" req from "+s+" not forwarded at ");
try {
throw is;
} catch (Exception e) {
}
}
}
public void destroy()
{
log("The instance was destroyed");
}
public String getRandomString(){
byte[] randbyte=new byte[10];
Random rand = new Random(System.currentTimeMillis());
for (int idx = 0; idx <10; ++idx) {
int randomInt = rand.nextInt(26); //0<=randomInt<26
//System.out.println(randomInt);
randbyte[idx]=(byte)(randomInt+65);
}
try {
String rs=new String(randbyte, "UTF-8");
//System.out.println(rs);
return rs;
} catch (Exception e) {
//System.out.println("bad string");
return "bad";
}
}
}
AccountBean.java
package mybeans;
import BH.*;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.ArrayList;
import java.util.Arrays;
import static java.util.Arrays.asList;
import java.sql.*;
public class AccountBean implements java.io.Serializable {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/cs4010";
static final String USER = "cs4010";
static final String PASS = "cs4010";
private String account="";
private String password="";
public AccountBean(){
}
public void setAccount(String a)
{
account = a;
}
public String getAccount()
{
return account;
}
public void setPassword(String p)
{
password = p;
}
public String getPassword(){
return password;
}
public void createAccount()
{
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
Statement stmt = conn.createStatement();
// System.out.println("here: "+Bytes_Hex.String2HexString(n));
String this_query="INSERT INTO ries_userpass (username, password) VALUES ("+account+","+password+");";
// System.out.println(this_query);
stmt.executeUpdate(this_query);
stmt.close();
conn.close();
} catch (Exception e) {
}
return ;
}
public boolean isPassword(String p) //make this to use
{
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
Statement stmt = conn.createStatement();
String this_query=" SELECT * from ries_userpass WHERE username="+account+";";
ResultSet rs = stmt.executeQuery(this_query);
while (rs.next()) {
password=Bytes_Hex.HexString2String(rs.getString("posts"));
if(password.equals(p))
{
rs.close();
stmt.close();
conn.close();
return true;
}
}
rs.close();
stmt.close();
conn.close();
}
catch (Exception e) {
return false;
}
return false;
}
}
add this statement import mybeans.*;, since you are using AccountBean but you are not importing that class package;
import BH.*;
import mybeans.*;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.util.function.*;
import static java.util.Arrays.asList;
import java.text.DateFormat;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;
public class sessionServlet extends HttpServlet {
private List<String[]> the_sessions;
private DateFormat df;
public static ReentrantLock thelock = new ReentrantLock();
public void init() throws ServletException {
the_sessions=new ArrayList<String[]>();
df=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
if ((!(req.getParameter("task")==null))&&(req.getParameter("task").trim().equals("deploy"))) {
PrintWriter out = res.getWriter();
out.println("<html>");
out.println("<body>");
out.println("<hr /><center><h1>sessionServlet Deployed</h1></center><hr />");
out.println("</body>");
out.println("</html>");
return;
}
Consumer <String> forwardTo =(s) ->ForwardTo(s,req,res);
boolean is_first_visit=true;
String[] this_session=new String[3];
String manager = req.getParameter("manager");
for (String [] a_session :the_sessions) {
if (a_session[0].equals(manager)) { //Found an active session
is_first_visit=false;
this_session=a_session;
break;
}
}
if ((req.getParameter("task")==null)&&(!is_first_visit)) {
the_sessions.remove(this_session);
is_first_visit=true; // just used http://hoare.cs.umsl.edu/servlet/js_test/sessionServlet
}
req.setAttribute("thesessioncount",the_sessions.size());
if (is_first_visit) {
if (the_sessions.size()==10) {
forwardTo.accept("noSessions.jsp"); //No Available Sessions
return;
}
String randomStr = getRandomString();
String[] new_session = {randomStr,df.format(new Date()),"need a name"};
the_sessions.add(new_session);
this_session=new_session;
req.setAttribute("manager",randomStr);
forwardTo.accept("startSession.jsp");
return;
}
String the_name="";
String the_pw="";
if (this_session[2].equals("need a name")) { //No name given yet
the_name=req.getParameter("whoisit");
the_pw=req.getParameter("passwd");
if ((the_name==null)||(the_name.trim().length()==0)||checkPW(the_name,the_pw)) { //checkPW returns false if correct
the_sessions.remove(this_session);
req.setAttribute("thesessioncount",the_sessions.size());
forwardTo.accept("startSession.jsp");
return; // didn't enter a name in startSession
}
}
this_session[2]=the_name.trim();
req.setAttribute("thename", this_session[2]);
if (tooLong(this_session[1],df.format(new Date()))) { //Has the session timed out?
the_sessions.remove(this_session);
forwardTo.accept("Expired.jsp");
return;
} else {
this_session[1]=df.format(new Date()); //reset the last session activity time
NotesBean thesenotes=new NotesBean();
if(req.getParameter("task").trim().equals("9")){
the_sessions.remove(this_session);
forwardTo.accept("exit.jsp");
return;
}
thelock.lock();
if (!req.getParameter("task").trim().equals("0")) { //add ACC here, also show/update posts
thesenotes.setAll(req.getParameter("java_source"),Integer.parseInt(req.getParameter("version")));
if (req.getParameter("task").trim().equals("2")) {
thesenotes.setNotes(req.getParameter("notes"),req.getParameter("java_source"),Integer.parseInt(req.getParameter("version")));
}
}
req.setAttribute("thesessioncount",the_sessions.size());
req.setAttribute("theBean",thesenotes);
req.setAttribute("manager",manager);
//req.setAttribute("theURL", "http://www.umsl.edu/~siegelj/turing.jpg");
forwardTo.accept("getNotes.jsp");
thelock.unlock();
return;
}
}//end doGet
boolean tooLong(String now,String then){
//Check amount of time that passed
return false;
}
boolean checkPW(String name,String password){
AccountBean theAccount = new AccountBean();
theAccount.setAccount(name);
if(theAccount.isPassword(password))
return false;
return true;
}
public void log(String s){
FileWriter fileWriter = null;
try {
String content =s+" at :"+new Date(System.currentTimeMillis()).toString()+"\n";
File theLogFile = new File("C:/Tomcat/webapps/js_test/session.log");
fileWriter = new FileWriter(theLogFile,true);
fileWriter.write(content);
} catch (IOException ex) {
} finally {
try {
fileWriter.close();
} catch (IOException ex) {
}
}
}
void ForwardTo(String s,HttpServletRequest req, HttpServletResponse res)
{
RequestDispatcher rd= req.getRequestDispatcher(s);
try {
rd.forward(req, res);
} catch (IOException|ServletException is) {
log(" req from "+s+" not forwarded at ");
try {
throw is;
} catch (Exception e) {
}
}
}
public void destroy()
{
log("The instance was destroyed");
}
public String getRandomString(){
byte[] randbyte=new byte[10];
Random rand = new Random(System.currentTimeMillis());
for (int idx = 0; idx <10; ++idx) {
int randomInt = rand.nextInt(26); //0<=randomInt<26
//System.out.println(randomInt);
randbyte[idx]=(byte)(randomInt+65);
}
try {
String rs=new String(randbyte, "UTF-8");
//System.out.println(rs);
return rs;
} catch (Exception e) {
//System.out.println("bad string");
return "bad";
}
}
}
I need to forward/craft request to another servlet from other servlet's service method manually. This servlet which calls another servlet, should extract the data from other servlet's response and send it's own response to client. How to achieve this kind of functionality?
Client <-----> Servlet1 <-----> Servlet2
I know it's bad design, but due the circumstances we have to introduce the functionality of Servlet2 to Servlet1
you need to use HttpServletResponseWrapper and override its getOutputStream Method.
CustomHttpServletResponseWrapper and CustomServletOutputStream are implementation for this.
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CustomHttpServletResponseWrapper extends HttpServletResponseWrapper {
private ServletOutputStream outputStream;
private PrintWriter writer;
private CustomServletOutputStream os;
public CustomHttpServletResponseWrapper(HttpServletResponse response) throws IOException {
super(response);
}
#Override
public ServletOutputStream getOutputStream() throws IOException {
if (writer != null) {
throw new IllegalStateException("getWriter() has already been called on this response.");
}
if (outputStream == null) {
outputStream = getResponse().getOutputStream();
os = new CustomServletOutputStream(outputStream);
}
return os;
}
#Override
public PrintWriter getWriter() throws IOException {
if (outputStream != null) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
if (writer == null) {
os = new CustomServletOutputStream(getResponse().getOutputStream());
writer = new PrintWriter(new OutputStreamWriter(os, getResponse().getCharacterEncoding()), true);
}
return writer;
}
#Override
public void flushBuffer() throws IOException {
if (writer != null) {
writer.flush();
} else if (outputStream != null) {
os.flush();
}
}
public byte[] getContent() {
if (os != null) {
return os.getContent();
} else {
return new byte[0];
}
}
}
customServletOutputStream.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
public class CustomServletOutputStream extends ServletOutputStream {
private OutputStream outputStream;
private ByteArrayOutputStream content;
public CustomServletOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
this.content = new ByteArrayOutputStream(1024);
}
#Override
public void write(int b) throws IOException {
outputStream.write(b);
content.write(b);
}
public byte[] getContent() {
return content.toByteArray();
}
#Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setWriteListener(WriteListener writeListener) {
// TODO Auto-generated method stub
}
}
your Main class:
use RequestDespetcher.include() to redirect request to s2 and pass CustomHttpServletResponseWrapper.
#ResponseBody
#RequestMapping("/s1")
public String s1(HttpServletRequest req, HttpServletResponse res) throws Exception{
RequestDispatcher rd = req.getRequestDispatcher("/oauth2/s2");
CustomHttpServletResponseWrapper wrappedResponse = new CustomHttpServletResponseWrapper(res);
rd.include(req, wrappedResponse);
wrappedResponse.flushBuffer();
byte[] result = wrappedResponse.getContent();
System.out.println("result of servlet 2 "+new String(result));
// here you got the result of servlet 2. manipulate it as you want.
return new String(result);
}
#ResponseBody
#RequestMapping("/s2")
public String s2(HttpServletRequest req, HttpServletResponse res){
return "hello from s2";
}
I've got the following code for a file upload with Apache's HTTP-Client (org.apache.http.client):
public static void main(String[] args) throws Exception
{
String fileName = "test.avi";
File file = new File(fileName);
String serverResponse = null;
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPut put = new HttpPut("http://localhost:8080/" + fileName);
FileEntity fileEntity = new FileEntity(file, "binary/octet-stream");
put.setEntity(fileEntity);
HttpResponse response = client.execute(put);
HttpEntity entity = response.getEntity();
if (entity != null)
{
serverResponse = EntityUtils.toString(entity);
System.out.println(serverResponse);
}
}
It work's quite well but now I want to have a progress bar which shows the progress of the file upload. How can this be made? I found a code snippet at File Upload with Java (with progress bar) but it is designed for Apache HTTP Client 3 (org.apache.commons.httpclient) and the RequestEntity class does not exist in Apache HTTP Client 4. ;(
Maybe someone of you has an approach?
Many greetings
Benny
I introduced a derived FileEntity that just counts the written bytes.
It uses OutputStreamProgress that does the actual counting (kind of a decorator to the actual OutputStream).
The advantage of this (and decoration in general) is that I do not need to copy the actual implementation, like the the actual copying from the file stream to the output stream. I can also change to use a different (newer) implementation, like the NFileEntity.
Enjoy...
FileEntity.java
public class FileEntity extends org.apache.http.entity.FileEntity {
private OutputStreamProgress outstream;
public FileEntity(File file, String contentType) {
super(file, contentType);
}
#Override
public void writeTo(OutputStream outstream) throws IOException {
this.outstream = new OutputStreamProgress(outstream);
super.writeTo(this.outstream);
}
/**
* Progress: 0-100
*/
public int getProgress() {
if (outstream == null) {
return 0;
}
long contentLength = getContentLength();
if (contentLength <= 0) { // Prevent division by zero and negative values
return 0;
}
long writtenLength = outstream.getWrittenLength();
return (int) (100*writtenLength/contentLength);
}
}
OutputStreamProgress.java
public class OutputStreamProgress extends OutputStream {
private final OutputStream outstream;
private volatile long bytesWritten=0;
public OutputStreamProgress(OutputStream outstream) {
this.outstream = outstream;
}
#Override
public void write(int b) throws IOException {
outstream.write(b);
bytesWritten++;
}
#Override
public void write(byte[] b) throws IOException {
outstream.write(b);
bytesWritten += b.length;
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
outstream.write(b, off, len);
bytesWritten += len;
}
#Override
public void flush() throws IOException {
outstream.flush();
}
#Override
public void close() throws IOException {
outstream.close();
}
public long getWrittenLength() {
return bytesWritten;
}
}
A new version using the package org.apache.commons.io.output from commons-io (2.4) and its class CountingOutputStream.
I changed the initial code to reflect my project needs to use a multipart form as input and the post method (this dues to the requirements imposed by the server side).
Consider that the delta of large file correspond in my tests to 4096 bytes. This means that the listener method counterChanged() is called every 4096 bytes of transfered data, what is acceptable for my use case.
The method looks like:
public void post(String url, File sendFile) {
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(url + "/" + sendFile.getName());
MultipartEntity multiEntity = new MultipartEntity();
MyFileBody fileBody = new MyFileBody(sendFile);
fileBody.setListener(new IStreamListener(){
#Override
public void counterChanged(int delta) {
// do something
System.out.println(delta);
}});
multiEntity.addPart("file", fileBody);
StringBody stringBody = new StringBody(sendFile.getName());
multiEntity.addPart("fileName", stringBody);
post.setEntity(multiEntity);
HttpResponse response = client.execute(post);
}
The class MyFileBody becomes:
public class MyFileBody extends FileBody {
private IStreamListener listener;
public MyFileBody(File file) {
super(file);
}
#Override
public void writeTo(OutputStream out) throws IOException {
CountingOutputStream output = new CountingOutputStream(out) {
#Override
protected void beforeWrite(int n) {
if (listener != null && n != 0)
listener.counterChanged(n);
super.beforeWrite(n);
}
};
super.writeTo(output);
}
public void setListener(IStreamListener listener) {
this.listener = listener;
}
public IStreamListener getListener() {
return listener;
}
}
Finally, the listener interface looks like:
public interface IStreamListener {
void counterChanged(int delta);
}
This answer extends kilaka's answer by adding a simple listener to the OutputStreamProgress.java class instead of having the public getProgress() method (I'm honestly not sure how you are suppose to call the getProgress() method since the thread will be executing inside of httpclient's code the entire time you might want to call getProgress()!).
Please note you'll need to extend the entity class for each entity type you want to use, and when you write your HttpClient code, you'll need to create the entity of that new type.
I wrote a very basic write listener that implements the WriteListener interface. This is where you'll add your logic to do something with the write reports from the OutputStreamProgress, something like updating a progress bar :)
Big thanks to kilaka for using the decorator idea to sneak in a counting outstream.
WriteLisener.java
public interface WriteListener {
void registerWrite(long amountOfBytesWritten);
}
OutputStreamProgress.java
import java.io.IOException;
import java.io.OutputStream;
public class OutputStreamProgress extends OutputStream {
private final OutputStream outstream;
private long bytesWritten=0;
private final WriteListener writeListener;
public OutputStreamProgress(OutputStream outstream, WriteListener writeListener) {
this.outstream = outstream;
this.writeListener = writeListener;
}
#Override
public void write(int b) throws IOException {
outstream.write(b);
bytesWritten++;
writeListener.registerWrite(bytesWritten);
}
#Override
public void write(byte[] b) throws IOException {
outstream.write(b);
bytesWritten += b.length;
writeListener.registerWrite(bytesWritten);
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
outstream.write(b, off, len);
bytesWritten += len;
writeListener.registerWrite(bytesWritten);
}
#Override
public void flush() throws IOException {
outstream.flush();
}
#Override
public void close() throws IOException {
outstream.close();
}
}
BasicWriteListener
public class BasicWriteListener implements WriteListener {
public BasicWriteListener() {
// TODO Auto-generated constructor stub
}
public void registerWrite(long amountOfBytesWritten) {
System.out.println(amountOfBytesWritten);
}
}
MultipartEntityWithProgressBar
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
public class MultipartEntityWithProgressBar extends MultipartEntity {
private OutputStreamProgress outstream;
private WriteListener writeListener;
#Override
public void writeTo(OutputStream outstream) throws IOException {
this.outstream = new OutputStreamProgress(outstream, writeListener);
super.writeTo(this.outstream);
}
public MultipartEntityWithProgressBar(WriteListener writeListener)
{
super();
this.writeListener = writeListener;
}
public MultipartEntityWithProgressBar(HttpMultipartMode mode, WriteListener writeListener)
{
super(mode);
this.writeListener = writeListener;
}
public MultipartEntityWithProgressBar(HttpMultipartMode mode, String boundary, Charset charset, WriteListener writeListener)
{
super(mode, boundary, charset);
this.writeListener = writeListener;
}
// Left in for clarity to show where I took from kilaka's answer
// /**
// * Progress: 0-100
// */
// public int getProgress() {
// if (outstream == null) {
// return 0;
// }
// long contentLength = getContentLength();
// if (contentLength <= 0) { // Prevent division by zero and negative values
// return 0;
// }
// long writtenLength = outstream.getWrittenLength();
// return (int) (100*writtenLength/contentLength);
// }
}
Hello guys!
I solved the problem myself and made a simple example to it.
If there are any questions, feel free to ask.
Here we go!
ApplicationView.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
public class ApplicationView implements ActionListener
{
File file = new File("C:/Temp/my-upload.avi");
JProgressBar progressBar = null;
public ApplicationView()
{
super();
}
public void createView()
{
JFrame frame = new JFrame("File Upload with progress bar - Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 300, 200);
frame.setVisible(true);
progressBar = new JProgressBar(0, 100);
progressBar.setBounds(20, 20, 200, 30);
progressBar.setStringPainted(true);
progressBar.setVisible(true);
JButton button = new JButton("upload");
button.setBounds(progressBar.getX(),
progressBar.getY() + progressBar.getHeight() + 20,
100,
40);
button.addActionListener(this);
JPanel panel = (JPanel) frame.getContentPane();
panel.setLayout(null);
panel.add(progressBar);
panel.add(button);
panel.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
try
{
sendFile(this.file, this.progressBar);
}
catch (Exception ex)
{
System.out.println(ex.getLocalizedMessage());
}
}
private void sendFile(File file, JProgressBar progressBar) throws Exception
{
String serverResponse = null;
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPut put = new HttpPut("http://localhost:8080/" + file.getName());
ProgressBarListener listener = new ProgressBarListener(progressBar);
FileEntityWithProgressBar fileEntity = new FileEntityWithProgressBar(file, "binary/octet-stream", listener);
put.setEntity(fileEntity);
HttpResponse response = client.execute(put);
HttpEntity entity = response.getEntity();
if (entity != null)
{
serverResponse = EntityUtils.toString(entity);
System.out.println(serverResponse);
}
}
}
FileEntityWithProgressBar.java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.entity.AbstractHttpEntity;
/**
* File entity which supports a progress bar.<br/>
* Based on "org.apache.http.entity.FileEntity".
* #author Benny Neugebauer (www.bennyn.de)
*/
public class FileEntityWithProgressBar extends AbstractHttpEntity implements Cloneable
{
protected final File file;
private final ProgressBarListener listener;
private long transferredBytes;
public FileEntityWithProgressBar(final File file, final String contentType, ProgressBarListener listener)
{
super();
if (file == null)
{
throw new IllegalArgumentException("File may not be null");
}
this.file = file;
this.listener = listener;
this.transferredBytes = 0;
setContentType(contentType);
}
public boolean isRepeatable()
{
return true;
}
public long getContentLength()
{
return this.file.length();
}
public InputStream getContent() throws IOException
{
return new FileInputStream(this.file);
}
public void writeTo(final OutputStream outstream) throws IOException
{
if (outstream == null)
{
throw new IllegalArgumentException("Output stream may not be null");
}
InputStream instream = new FileInputStream(this.file);
try
{
byte[] tmp = new byte[4096];
int l;
while ((l = instream.read(tmp)) != -1)
{
outstream.write(tmp, 0, l);
this.transferredBytes += l;
this.listener.updateTransferred(this.transferredBytes);
}
outstream.flush();
}
finally
{
instream.close();
}
}
public boolean isStreaming()
{
return false;
}
#Override
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
ProgressBarListener.java
import javax.swing.JProgressBar;
public class ProgressBarListener
{
private int transferedMegaBytes = 0;
private JProgressBar progressBar = null;
public ProgressBarListener()
{
super();
}
public ProgressBarListener(JProgressBar progressBar)
{
this();
this.progressBar = progressBar;
}
public void updateTransferred(long transferedBytes)
{
transferedMegaBytes = (int) (transferedBytes / 1048576);
this.progressBar.setValue(transferedMegaBytes);
this.progressBar.paint(progressBar.getGraphics());
System.out.println("Transferred: " + transferedMegaBytes + " Megabytes.");
}
}
Happy Coding!