I have a server that handles requests, and with regular intervals (every 1-2 minutes) needs to call another server and update a list of objects that is used to create the response to the request. Inspired by for example the accepted answer for this question, I tried to use the Schedule annotation, but can't get it to work.
How to run a background task in a servlet based web application?
A simplified view of the server is:
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(name = "MyServer", urlPatterns = {"/data/*", "/scheduled/*"}, loadOnStartup = 1)
public class MyServlet extends HttpServlet {
private static final String UTF_8 = "UTF-8";
private static final String APPLICATION_JSON = "application/json";
private static final long serialVersionUID = 1L;
private static connector connector;
public MyServlet() {
super();
}
public void destroy() {}
#Override
public void init() throws ServletException {
connector = new connector();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getServletPath();
String pathInfo = request.getPathInfo().substring(1);
response.setContentType(APPLICATION_JSON);
response.setCharacterEncoding(UTF_8);
if (path.endsWith("/data")) {
List<DataItem> dataItems = connector.currentData;
response.getWriter().write(JsonUtility.convertToJsonString(dataItems));
} else if (path.endsWith("/scheduled")) {
connector.fetchData();
response.getWriter().write("Done");
} else {
response.getWriter()
.write(pathInfo + " Is not Found but not returning 404");
return;
}
}
}
The connector class that is supposed to update the stored data from the other server at regular intervals is:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
#Startup
#Singleton
public class Connector {
public List<DataItem> currentData = new LinkedList<>();
#Lock(LockType.READ)
#Schedule(second = "*", minute = "*/2", hour = "*", persistent = false)
public void fetchNews() {
logger.debug("Fetching data");
String response = sendGet(url, bearerToken);
JsonObject json = new Gson().fromJson(response, JsonObject.class);
//Transform the response to a list of DataItems.
List<DataItem> retrievedData = toDataList(json)
System.out.println(retrievedData);
synchronized(currentData) {
currentData = retrievedData;
}
}
private String sendGet(String path, String authorizationProperty) {
URL url;
try {
url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", authorizationProperty);
conn.setRequestProperty("Content-Type","application/json");
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String output;
StringBuffer response = new StringBuffer();
while ((output = in.readLine()) != null) {
response.append(output);
}
in.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
However, the method fetchData is not firing every second minute as I was expecting. I don't know what I am missing. I have played around a bit with adding/removing the #Startup annotation, creating an instance of the class in the init() method on the server, but still have no result.
Related
I am writing some code to collect some controller's request param and response body.
Since the project framework is apache CXF, which version is 3.1.18,
I write an interceptor extends AbstractPhaseInterceptor to collect param in phase Phase.RECEIVE, which is working.
But when a write an outInterceptor extends AbstractPhaseInterceptor to collect the response of the controller, I find there no way for me to do this, there just one method handleMessage(Message message) in the interceptor, I can not fetch anything I want from the message
Can anybody help me? I am new to CXF. Thanks!
I found the answer from the other blob
package XXX.web.webservice.interceptor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
public class ArtifactOutInterceptor extends AbstractPhaseInterceptor<Message>{
private static final Logger log = Logger.getLogger(ArtifactOutInterceptor.class);
public ArtifactOutInterceptor() {
//这儿使用pre_stream,意思为在流关闭之前
super(Phase.PRE_STREAM);
}
public void handleMessage(Message message) {
try {
OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);
message.getInterceptorChain().doIntercept(message);
CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
InputStream in = csnew.getInputStream();
String xml = IOUtils.toString(in);
//这里对xml做处理,处理完后同理,写回流中
IOUtils.copy(new ByteArrayInputStream(xml.getBytes()), os);
cs.close();
os.flush();
message.setContent(OutputStream.class, os);
} catch (Exception e) {
log.error("Error when split original inputStream. CausedBy : " + "\n" + e);
}
}
private class CachedStream extends CachedOutputStream {
public CachedStream() {
super();
}
protected void doFlush() throws IOException {
currentStream.flush();
}
protected void doClose() throws IOException {
}
protected void onWrite() throws IOException {
}
}
}
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);
}
}
We have JAX RS implementation which needs to send back JSON output. But the response size is huge. And the client expects the same synchronously.
Hence I tried to use StreamingOutput... but the client is not really getting the data in chunks.
Below is sample snippet:
Server Side
streamingOutput = new StreamingOutput() {
#Override
public void write(OutputStream out) throws IOException, WebApplicationException {
JsonGenerator jsonGenerator = mapper.getFactory().createGenerator(out);
jsonGenerator.writeStartArray();
for(int i=0; i < 10; i++) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("Response_State", "Response State - " + i);
jsonGenerator.writeStringField("Response_Report", "Response Report - " + i);
jsonGenerator.writeStringField("Error_details", "Error Details - " + i);
jsonGenerator.writeEndObject();;
jsonGenerator.flush();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
jsonGenerator.writeEndArray();
jsonGenerator.close();
}
};
return Response.status(200).entity(streamingOutput).build();
Client
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost("http://localhost:8080/AccessData/FetchReport");
post.setHeader("Content-type", "application/json");
ResponseHandler<HttpResponse> responseHandler = new BasicResponseHandler();
StringEntity entity = new StringEntity(jsonRequest); //jsonRequest is request string
post.setEntity(entity);
HttpResponse response = client.execute(post);
BufferedReader buffReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
JsonParser jsonParser = new JsonFactory().createParser(buffReader);
while(jsonParser.nextToken() != JsonToken.END_OBJECT) {
System.out.println(jsonParser.getCurrentName() + ":" + jsonParser.getCurrentValue());
}
String output;
while((output = buffReader.readLine()) != null) {
System.out.println(output);
}
In the server side code, I am putting sleep call just to simulate a gap between chunks of data. What I need is that the client should receive chunks of data as and when it is thrown back by the server.
But here the client gets the response in entirety always.
Any possible solution?
Thanks in advance.
It looks like the client side is not implemented correctly: reading the array of the objects using the parser.
Also, I would like to recommend reading and writing a data transfer object instead of low level field-by-field reading and writing.
For the sake of completeness, here is a complete draft example that uses: Jersey 2.25.1, Jetty 9.2.14.v20151106.
Common
ResponseData class
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ResponseData {
private final String responseState;
private final String responseReport;
private final String errorDetails;
#JsonCreator
public ResponseData(
#JsonProperty("Response_State") final String responseState,
#JsonProperty("Response_Report") final String responseReport,
#JsonProperty("Error_details") final String errorDetails) {
this.responseState = responseState;
this.responseReport = responseReport;
this.errorDetails = errorDetails;
}
public String getResponseState() {
return this.responseState;
}
public String getResponseReport() {
return this.responseReport;
}
public String getErrorDetails() {
return this.errorDetails;
}
#Override
public String toString() {
return String.format(
"ResponseData: responseState: %s; responseReport: %s; errorDetails: %s",
this.responseState,
this.responseReport,
this.errorDetails
);
}
}
Service
ServerProgram class
import java.net.URI;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
import org.glassfish.jersey.server.ResourceConfig;
public class ServerProgram {
public static void main(final String[] args) {
final URI uri = URI.create("http://localhost:8080/");
final ResourceConfig resourceConfig = new ResourceConfig(TestResource.class);
resourceConfig.register(JacksonFeature.class);
JettyHttpContainerFactory.createServer(uri, resourceConfig);
}
}
TestResource class
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.OutputStream;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
#Path("/")
public class TestResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getData() {
final StreamingOutput streamingOutput = new JsonStreamingOutput();
return Response.status(200).entity(streamingOutput).build();
}
private static class JsonStreamingOutput implements StreamingOutput {
#Override
public void write(final OutputStream outputStream) throws IOException, WebApplicationException {
final ObjectMapper objectMapper = new ObjectMapper();
final JsonFactory jsonFactory = objectMapper.getFactory();
try (final JsonGenerator jsonGenerator = jsonFactory.createGenerator(outputStream)) {
jsonGenerator.writeStartArray();
for (int i = 0; i < 10; i++) {
final ResponseData responseData = new ResponseData(
"Response State - " + i,
"Response Report - " + i,
"Error Details - " + i
);
jsonGenerator.writeObject(responseData);
jsonGenerator.flush();
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
jsonGenerator.writeEndArray();
}
}
}
}
Client
ClientProgram class
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.client.ClientProperties;
public class ClientProgram {
public static void main(final String[] args) throws IOException {
Client client = null;
try {
client = ClientBuilder.newClient();
client.property(ClientProperties.READ_TIMEOUT, 10000);
try (final InputStream inputStream = client
.target("http://localhost:8080/")
.request(MediaType.APPLICATION_JSON)
.get(InputStream.class);
final BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
processStream(bufferedInputStream);
}
} finally {
if (client != null) {
client.close();
}
}
}
private static void processStream(final InputStream inputStream) throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
final JsonFactory jsonFactory = objectMapper.getFactory();
try (final JsonParser jsonParser = jsonFactory.createParser(inputStream)) {
final JsonToken arrayToken = jsonParser.nextToken();
if (arrayToken == null) {
// TODO: Return or throw exception.
return;
}
if (!JsonToken.START_ARRAY.equals(arrayToken)) {
// TODO: Return or throw exception.
return;
}
// Iterate through the objects of the array.
while (JsonToken.START_OBJECT.equals(jsonParser.nextToken())) {
final ResponseData responseData = jsonParser.readValueAs(ResponseData.class);
System.out.println(responseData);
}
}
}
}
Hope this helps.
I'm trying to write a bare-bones health check servlet for my app, just to see if my Tomcat server is running. Essentially, it's a servlet with a "/health" endpoint that is an empty page. Below is my code:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
public class HealthCheckServlet extends HttpServlet
{
private static final String SUCCESS = "Success";
private static final String FAILURE = "Failure";
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
isConnectionOK(request);
}
private static String isConnectionOK(HttpServletRequest request) throws IOException
{
String status = "";
try
{
URL connectionURL = new URL(request.getRequestURL().toString() + "/health");
HttpURLConnection connection = (HttpURLConnection) connectionURL.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int httpResponseCode = connection.getResponseCode();
if (httpResponseCode == 200)
{
status = SUCCESS;
}
}
catch (IOException e)
{
status = FAILURE;
}
return status;
}
}
When I navigate to localhost:8080/health and debug it, it reaches my breakpoint at URL connectionURL = new URL(request.getRequestURL().toString() + "/health"); but won't progress to any subsequent breakpoints. The page itself returns a status code of 200, so I'm just trying to get the code to pick up on that.
Am I doing something wrong with trying to establish this connection within a servlet, or is there another problem here?
I'm learning about servlets in java. Bellow is my code that is suppose to get the content of the url, store it in array list and, display it on the screen. for some reason I'm unable to get the string array content to displayed on the screen. When I load the page I get the "no luck" message. Any ideas why? thanks
//package fortune;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static java.util.Arrays.*;
import java.util.Collections;
import java.util.List;
#WebServlet(name = "FortuneServlet", urlPatterns = {"/"})
public class FortuneServlet extends HttpServlet {
//private String [] cookies = null;
List<String> cookies = new ArrayList<>();
String line ;
public void geturl(String[] args) {
try
{
URL url = new URL(" http://fortunes.cat-v.org/openbsd/");
//URL url = new URL(" http://bbc.com");
// read text returned by server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
while((line = in.readLine()) != null)
{
cookies.add(line);
//line = in.readLine();
}
in.close();
}
catch (java.net.MalformedURLException e) {
System.out.println("Malformed URL: " + e.getMessage());
}
catch (IOException e) {
System.out.println("I/O Error: " + e.getMessage());
}
}
public void init() throws ServletException {
}
#Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/plain");
if (cookies != null)
{
//response.getWriter().println(
// cookies[new Random().nextInt(cookies.length)]
//);
for (String str: cookies)
{
Collections.shuffle(cookies);
response.getWriter().println(str);
}
}
else {
response.getWriter().println("No luck!");
}
}
}
cookies is always an empty list (unless you are not showing something to us), so you always shuffle it and try to display, but because you don't have anything there you see a blank page.
I would change check cookies != null to !cookies.isEmpty().
EDIT:
You are not adding anything to the cookies list, so it is empty (List<String> cookies = new ArrayList<>();).
Maybe you wanted to call geturl (which does some add on the cookies list) method somewhere in the doGet? Right now it is not used anywhere.