Receiving an Ajax Request in a Servlet using ObjectInputStream? - ajax

I am sending my Ajax Request in the following format
xmlhttp.open("POST","http://172.16.xx.xx:8080/ajax/validate",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(send); //where send is a string retrieved from textarea
This is my Servlet code
ObjectInputStream in =new ObjectInputStream(request.getInputStream());
String inputxmlstring=(String) in.readObject();
I am getting the following exception
java.io.StreamCorruptedException: invalid stream header: 3C3F786D
What is the problem with the code? Is there anything wrong with my request header content type?
EDIT 1
BufferedInputStream in =new BufferedInputStream(req.getInputStream());
byte[] buf=new byte[req.getContentLength()];
while(in.available()>0)
{
in.read(buf);
}
String inputxmlstring=new String(buf);
System.out.println(inputxmlstring);
If I use this code for Servlet I get the following error
14:13:27,828 INFO [STDOUT] [Fatal Error] :1:1: Content is not allowed in prolog
.
14:13:27,843 INFO [STDOUT] org.xml.sax.SAXParseException: Content is not allowe
d in prolog.
EDIT 2
I use this code to parse. The String inputxmlstring has been used in Edit1.
DocumentBuilderFactory fty1 = DocumentBuilderFactory.newInstance();
fty1.setNamespaceAware(true);
DocumentBuilder builder1 = fty1.newDocumentBuilder();
ByteArrayInputStream bais1 = new ByteArrayInputStream(inputxmlstring.getBytes());
Document xmldoc1=builder1.parse(bais1);

You should use the ObjectInputStream only if you know the other end it was written using ObjectOutputStream.
When the client uses ObjectOutputStream, it writes special bytes indicating it is object stream. If these bytes are not present ObjectInputStream will throw StreamCorruptedException.
In your case you should read using request.getInputStream() because the XMLHttpRequest is not sending using ObjectOutputStream.

Related

Apache Camel with Spring Boot - Zip process

I am trying to process a zip file with Apache Camel.
After making a call, I get a zip file and try to prepare the next call with this zip file as body.
The call requires a form data with one name and zip file as value.
I handle in this way:
process(e ->{
Object zip = e.getIn().getBody();
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file",zip);
e.getIn().setBody(body);
})
But I receive the exception:
org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.springframework.util.LinkedMultiValueMap to the required type: java.io.InputStream with value {file=[[B#2b02c691]}
Any Ideas?
Cheers!
I tried to get the response in byte[] but it still dose not work.
As Jeremy said, the error says Camel is expecting (further in the process) a body of type InputStream, whilst you are obviously preparing a body of type MultiValueMap (BTW: why use a map if you have a single object to handle ??)
I do not know what is the concrete type of your 'zip' object, but (if needed) you may have to replace current body with its inputstream equivalent:
process(e ->{
// Print concrete type
Object zip = e.getMessage().getBody();
System.out.println("Type is " + zip.getClass() );
// Convert body
InputStream is = e.getMessage().getBody(InputStream.class);
// Replace body
e.getMessage().setBody(is);
})

Get message content from mime message?

I have a java spring integration project that is receving emails through the below code:
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext(
"/integration/gmail-imap-idle-config.xml");
DirectChannel inputChannel = ac.getBean("receiveChannel", DirectChannel.class);
inputChannel.subscribe(message -> {
org.springframework.messaging.Message<MimeMailMessage> received =
(org.springframework.messaging.Message<MimeMailMessage>) message;
log.info("content" + message);
List<String> sentences = null;
try {
} catch (Exception e) {
}
I get the email, and I can get the subject, but I can never actually extract the message body. How do I do this?
Thank you!
You have to use this option on the channel adapter:
simple-content="true"
See its description:
When 'true', messages produced by the source will be rendered by 'MimeMessage.getContent()'
which is usually just the body for a simple text email. When false (default) the content
is rendered by the 'getContent()' method on the actual message returned by the underlying
javamail implementation.
For example, an IMAP message is rendered with some message headers.
This attribute is provided so that users can enable the previous behavior, which just
rendered the body.
But still it is doubtful, since I see in case of GMail message it is never simple. The content is a MimeMultipart and we need to read its parts to get access to the real body.
So, this is how you should change your code as well:
log.info("content" + ((MimeMultipart) ((MimeMessage) message.getPayload()).getContent()).getBodyPart(0).getContent());

CRFClassifier: loading model from a stream gives exception "invalid stream header: 1F8B0800"

I am trying to load a CRFClassifier model from a file. This way works:
// this works
classifier = CRFClassifier.getClassifier("../res/stanford-ner-2018-02-27/classifiers/english.all.3class.distsim.crf.ser.gz");
When I want to use stream, however, I get invalid stream header: 1F8B0800 exception:
// this throws an exception
String modelResourcePath = "../res/stanford-ner-2018-02-27/classifiers/english.all.3class.distsim.crf.ser.gz";
BufferedInputStream stream = new BufferedInputStream(new FileInputStream(modelResourcePath));
classifier = CRFClassifier.getClassifier(stream);
Exception:
Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 1F8B0800
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:866)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:358)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.loadClassifier(AbstractSequenceClassifier.java:1473)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.loadClassifier(AbstractSequenceClassifier.java:1456)
at edu.stanford.nlp.ie.crf.CRFClassifier.getClassifier(CRFClassifier.java:2890)
at com.sv.research.ner.stanford.StanfordEntityExtractor.<init>(StanfordEntityExtractor.java:34)
at com.sv.research.ner.stanford.StanfordEntityExtractor.main(StanfordEntityExtractor.java:59)
I would expect both ways to be equivalent. My reason to load through a stream is that ultimately I want to load the model from JAR resources using:
stream = ClassLoader.getSystemClassLoader().getResourceAsStream(modelResourcePath));
The way the classifier you are trying to use was serialized via GZIPInputStream as far as I could see from their sources.
So can you try deserializing the way that they serialize, like this:
BufferedInputStream stream = new BufferedInputStream(new GZIPInputStream(new FileInputStream(modelResourcePath)));
Cheers

Send Status code and message in SpringMVC

I have the following code in my web application:
#ExceptionHandler(InstanceNotFoundException.class)
#ResponseStatus(HttpStatus.NO_CONTENT)
public ModelAndView instanceNotFoundException(InstanceNotFoundException e) {
return returnErrorPage(message, e);
}
Is it possible to also append a status message to the response? I need to add some additional semantics for my errors, like in the case of the snippet I posted I would like to append which class was the element of which the instance was not found.
Is this even possible?
EDIT: I tried this:
#ResponseStatus(value=HttpStatus.NO_CONTENT, reason="My message")
But then when I try to get this message in the client, it's not set.
URL u = new URL ( url);
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
huc.setRequestMethod("GET");
HttpURLConnection.setFollowRedirects(true);
huc.connect();
final int code = huc.getResponseCode();
String message = huc.getResponseMessage();
Turns out I needed to activate custom messages on Tomcat using this parameter:
-Dorg.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER=true
The message can be in the body rather than in header. Similar to a successful method, set the response (text, json, xml..) to be returned, but set the http status to an error value. I have found that to be more useful than the custom message in header. The following example shows the response with a custom header and a message in body. A ModelAndView that take to another page will also be conceptually similar.
#ExceptionHandler(InstanceNotFoundException.class)
public ResponseEntity<String> handle() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("ACustomHttpHeader", "The custom value");
return new ResponseEntity<String>("the error message", responseHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}

How do I pass the result from httpget to SAX parser

I'm want to make a request to google API and pass the resulting XML to SAX parser here are both codes...
First the request:
HttpClient hclient = new DefaultHttpClient();
HttpGet get = new HttpGet("http://www.google.com/ig/api?weather=Cardiff");
HttpResponse hrep = hclient.execute(get);
HttpEntity httpEntity = hrep.getEntity();
Then the parser:
SAXParserFactory saxpf = SAXParserFactory.newInstance();
SAXParser saxp = saxpf.newSAXParser();
XMLReader xr = saxp.getXMLReader();
ExHandler myHandler = new ExHandler();
xr.setContentHandler(myHandler);
xr.parse();
Is this the right way to do this and how do I connect both codes.
Thanks in advance
The SAXParser object can take in an input stream and the handler. So something like:
SAXParser saxParser = factory.newSAXParser();
XMLParser parser = new XMLParser();
saxParser.parse(httpEntity.getContent(),parser);
The getContent() method returns and input stream from the HttpRequest, and the XMLParser object is just a class I created (supposedly) that contains the definition of how to parse the XML.
EDIT*
You really should read the entire API for SAXParser, it has several overloaded methods:
void parse(InputSource is, DefaultHandler dh)
Parse the content given InputSource as XML using the specified DefaultHandler.
void parse(InputSource is, HandlerBase hb)
Parse the content given InputSource as XML using the specified HandlerBase.
void parse(InputStream is, DefaultHandler dh)
Parse the content of the given InputStream instance as XML using the specified DefaultHandler.
void parse(InputStream is, DefaultHandler dh, String systemId)
Parse the content of the given InputStream instance as XML using the specified DefaultHandler.
void parse(InputStream is, HandlerBase hb)
Parse the content of the given InputStream instance as XML using the specified HandlerBase.
void parse(InputStream is, HandlerBase hb, String systemId)
Parse the content of the given InputStream instance as XML using the specified HandlerBase.
Some of the methods take an InputSource, some take an InputStream, as I stated earlier.

Resources