FOMUnsupportedTextTypeException: Unsupported Text Type: text/html - websphere-portal

I am trying to parse the response atom feed received from websphere portal after rest call using apache abdera. However receiving the below error when parsing. Could some one let me know what the issue is?
org.apache.abdera.parser.stax.FOMUnsupportedTextTypeException: Unsupported Text Type: text/html
Abdera abdera = new Abdera();
AbderaClient abderaClient = new AbderaClient(abdera);
Factory factory = abdera.getFactory();
Cookie[] cookies=request.getCookies();
org.apache.commons.httpclient.Cookie ltpaCookieHttpCommons = new org.apache.commons.httpclient.Cookie();
RequestOptions options = new RequestOptions(true);
List<String> cookieStrings = new ArrayList<String>();
options.setHeader("Cookie", (String[])cookieStrings.toArray(new String[cookieStrings.size()]));
ClientResponse resp = abderaClient.get("http://localhost:10039/wps/contenthandler/!ut/p/digest!W9TQFjuU7ADCwtSkxDsxHg/searchfeed/search?queryLang=en&locale=en&resultLang=en&query=test&scope=com.ibm.lotus.search.ALL_SOURCES&start=0&results=10&output=application/xml", options);
System.out.println(resp.getType());
if (resp.getType() == ResponseType.SUCCESS) {
System.out.println("!!!!!!Response success!!!!!!");
Document<Feed> docFeed = resp.getDocument();
// JSON Output
Writer writer = abdera.getWriterFactory().getWriter("json");
try {
Feed feed=docFeed.getRoot();
abdera.getWriterFactory().getWriter("json").writeTo(feed, System.out);
} catch(Exception e) {
e.printStackTrace();
}
} else {
}

The issue is that the atom feed your parsing has a type tag with text/html in it which isn't in the atom spec so abdera throws the above error.
According to the spec:
When present, the value
MUST be one of "text", "html", or "xhtml"
Are you sure the feed is an atom feed and not an RSS feed which supports enclosures with MIME types like the one above ?

Related

Throwing error while downloading file in ASP.NET Core with status code 400

I'm working on download feature. When I run code on localhost, it runs perfectly without any error. But when I uploads same code to server then it returns Failed to load resource: the server responded with a status of 400 (Bad Request) error in console of browser. For requesting and getting response from server, I have used Axios. I'm newbie to ASP.NET Core + ReactJS technology stack and working on APIs for the first time so it's being difficult for me to figuring out root cause of this error.
Here is my code for requesting data from server.
axios({
method: 'POST',
url: '/api/ImageFetch/ImageFetchPoint',
responseType: 'blob',// important
headers: {
'Content-Type': 'application/json'
},
data: filepath
}).then(function(response) {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
}).catch(error => {
console.log("Status:", error.response.status);
console.log("Data:", error.response.data);
});
For getting response as file(any extension) from server, I've used following code.
[HttpPost("PanImageFunction")]
[Route("api/[controller]/[action]")]
public async Task<IActionResult> ImageFetchFunction([FromBody] ImageFetchRequest request)
{
var filePath = request.ImagePath;
var filename = System.IO.Path.GetFileName(filePath);
string path="unknownpath";
try {
if (filename == null)
return Content("filename not present");
path = Path.Combine(
Directory.GetCurrentDirectory(),
"RegistrationImages", filename);
} catch(Exception ex) {
new Logger().write(ex);
}
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = false // false = prompt the user for downloading; true = browser to try to show the file inline
};
Response.Headers.Add("Content-Type", "multipart/form-data");
Response.Headers.Add("Content-Disposition", cd.ToString());
Response.Headers.Add("X-Content-Type-Options", "nosniff");
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
private string GetContentType(string path)
{
var types = GetMimeTypes();
var ext = Path.GetExtension(path).ToLowerInvariant();
return types[ext];
}
private Dictionary<string, string> GetMimeTypes()
{
return new Dictionary<string, string>
{
{".txt", "text/plain"},
{".pdf", "application/pdf"},
{".doc", "application/vnd.ms-word"},
{".docx", "application/vnd.ms-word"},
{".xls", "application/vnd.ms-excel"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"},
{".csv", "text/csv"}
};
}
Complete code works perfectly on localhost. But when I uploads it on server then it throws 400 bad request error on console of browser as you can see in following image.
I have checked many forums and articles but most of the articles related to ASP.NET core giving solution related to Razor pages and not giving solutions related to ReactJS and Axios.
How can I fix this error?

Send a PDF as an attachment through Sendgrid

I'm using Sendgrid to send emails through an app on GAE. It's working fine, but I also want to be able to send PDFs as an attachment.
I'm not using Sendgrid.jar file in my project. I've just used Sendgrid.java. And this class has no methods by which i can add attachments. Can someone help me?
public static boolean sendEmail(String fromMail, String title, String toMail, String message) throws IOException {
Email from = new Email(fromMail);
String subject = title;
Email to = new Email(toMail);
Content content = new Content("text/html", message);
Mail mail = new Mail(from, subject, to, content);
Path file = Paths.get("file path");
Attachments attachments = new Attachments();
attachments.setFilename(file.getFileName().toString());
attachments.setType("application/pdf");
attachments.setDisposition("attachment");
byte[] attachmentContentBytes = Files.readAllBytes(file);
String attachmentContent = Base64.getMimeEncoder().encodeToString(attachmentContentBytes);
String s = Base64.getEncoder().encodeToString(attachmentContentBytes);
attachments.setContent(s);
mail.addAttachments(attachments);
SendGrid sg = new SendGrid("sendgrid api key");
Request request = new Request();
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
if (response != null) {
return true;
} else {
return false;
}
}
Define above static method and call with relevant arguments as your program wants.
Here is the code of a servlet that sends a mail with a PDF as attachment, through Sendgrid:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
....
ByteArrayOutputStream os = null;
try {
PDFGenerator pdfGenerator = new PDFGenerator(invoiceOut);
os = pdfGenerator.getPDFOutputStream();
} catch (Exception e) {
....
}
SendGrid sendgrid = new SendGrid(Constants.SENDGRID_API_KEY);
SendGrid.Email email = new SendGrid.Email();
email.addTo(....);
email.setFrom(....);
email.setFromName(....);
email.setSubject(....);
email.setHtml("......");
ByteBuffer buf = null;
if (os == null) {
//error...
} else {
buf = ByteBuffer.wrap(os.toByteArray());
}
InputStream attachmentDataStream = new ByteArrayInputStream(buf.array());
try {
email.addAttachment("xxxxx.pdf", attachmentDataStream);
SendGrid.Response response = sendgrid.send(email);
} catch (IOException e) {
....
throw new RuntimeException(e);
} catch (SendGridException e) {
....
throw new RuntimeException(e);
}
}
PDFGenerator is one of my classes in which getPDFOutputStream method returns the PDF as ByteArrayOutputStream.
I personally find it easier to directly construct the JSON request body as described in the API docs than to use Sendgrid's libraries. I only use the Sendgrid library for sending the request after I construct the JSON data myself.
When constructing the JSON data you need to specify at least a filename and the content (i.e., the PDF file). Make sure to Base64 encode the PDF file before adding it to the JASON data.
I'd include some code, but I do Python and not Java so not sure that would help.

Attaching a video stream through the .NET Mirror API

I am trying to attach a video stream using the .NET Mirror API, but I'm having some trouble.
I can't seem to find a method that supports the format referenced here:
POST /upload/mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: multipart/related; boundary="mymultipartboundary"
Content-Length: {length}
--mymultipartboundary
Content-Type: application/json; charset=UTF-8
{ "text": "Skateboarding kittens" }
--mymultipartboundary
Content-Type: video/vnd.google-glass.stream-url
http://example.com/path/to/kittens.mp4
--mymultipartboundary--
The best info from Google I've seen is to use the following method to do the insert:
/// <summary>
/// Insert a new timeline item in the user's glass with an optional
/// notification and attachment.
/// </summary>
/// <param name='service'>Authorized Mirror service.</param>
/// <param name='text'>Timeline Item's text.</param>
/// <param name='contentType'>
/// Optional attachment's content type (supported content types are
/// "image/*", "video/*" and "audio/*").
/// </param>
/// <param name='attachment'>Optional attachment stream</param>
/// <param name='notificationLevel'>
/// Optional notification level, supported values are null and
/// "AUDIO_ONLY".
/// </param>
/// <returns>
/// Inserted timeline item on success, null otherwise.
/// </returns>
public static TimelineItem InsertTimelineItem(MirrorService service,
String text, String contentType, Stream attachment,
String notificationLevel) {
TimelineItem timelineItem = new TimelineItem();
timelineItem.Text = text;
if (!String.IsNullOrEmpty(notificationLevel)) {
timelineItem.Notification = new NotificationConfig() {
Level = notificationLevel
};
}
try {
if (!String.IsNullOrEmpty(contentType) && attachment != null) {
// Insert both metadata and media.
TimelineResource.InsertMediaUpload request = service.Timeline.Insert(
timelineItem, attachment, contentType);
request.Upload();
return request.ResponseBody;
} else {
// Insert metadata only.
return service.Timeline.Insert(timelineItem).Fetch();
}
} catch (Exception e) {
Console.WriteLine("An error occurred: " + e.Message);
return null;
}
}
However, this code takes the content to "attach" as a stream (which is great for, say, uploading an image, which I've tested and had work). But, a streaming video requires only the URL of the video.
I've tried sending in the string representation of the URL as a stream, but the result is just a video that loads indefinitely.
I've successfully been able to get the video to play by making a cURL request using my auth token and the POST request above, so I know the video itself isn't the issue.
Has anyone been able to get streaming video to work through .NET (either with the Mirror API or with a custom WebRequest of some sort?) I've tried creating the WebRequest myself from scratch, but I'm getting 400's as a response.
For reference, the other code I've tried:
var request = WebRequest.CreateHttp(baseAddress + method);
request.Method = "POST";
request.Headers.Add("Authorization", string.Format("Bearer {0}", auth));
string itemJson = JsonConvert.SerializeObject(item.Item, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
string contentFormat = "--MyBound\nContent-Type: application/json; charset=UTF-8\n\n{0}\n--MyBound\nContent-Type: video/vnd.google-glass.stream-url\n\n{1}\n--MyBound--";
string content = string.Format(contentFormat, new[] { itemJson, item.VideoUrl });
request.ContentLength = content.Length;
request.ContentType = "multipart/related; boundary=\"MyBound\"";
var rs = request.GetRequestStream();
using (var sw = new StreamWriter(rs))
{
sw.Write(content);
}
var response = request.GetResponse();
Where item is a class I've written that contains the VideoUrl as a string, and the Item (a TimelineItem from the Mirror API), and where the video Url I'm using is:
http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8
Thanks in advance, everyone!
I have success with following code.
String mediaLink = "url_to_your_video.mp4";
String message = "you_message";
MirrorService Service = new MirrorService(new BaseClientService.Initializer()
{
Authenticator = Utils.GetAuthenticatorFromState(state)
});
TimelineItem timelineItem = new TimelineItem();
timelineItem.Creator = new Contact()
{
Id = Config.CREATOR_ID,
DisplayName = Config.DISPLAY_NAME,
};
timelineItem.Notification = new NotificationConfig() { Level = "DEFAULT" };
timelineItem.MenuItems = new List<MenuItem>()
{
new MenuItem() {Action = "NAVIGATE"},
new MenuItem() {Action = "DELETE"},
new MenuItem() {Action = "SHARE"},
};
if (!String.IsNullOrEmpty(mediaLink))
{
Stream stream = null;
if (mediaLink.StartsWith("/"))
{
stream = new StreamReader(Server.MapPath(mediaLink)).BaseStream;
}
else
{
HttpWebRequest request = WebRequest.Create(mediaLink) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
byte[] b = null;
using (Stream streamFromWeb = response.GetResponseStream())
using (MemoryStream ms = new MemoryStream())
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = streamFromWeb.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (streamFromWeb.CanRead && count > 0);
b = ms.ToArray();
stream = new MemoryStream(b);
}
}
Service.Timeline.Insert(timelineItem, stream, "video/mp4").Upload();
}
else
{
Service.Timeline.Insert(timelineItem).Fetch();
}
Sanath's code is fine for small files, but you really don't want to be doing a binary upload of anything large to Glass.
The documentation on the Glass site is kind of misleading, they go on at length about how to do multi-part uploads, but then tell you that they aren't a good idea and briefly mention how you should do it.
Glass actually supports progressive download and hls streaming directly from the timeline. You'll want to create a standard image card with a thumbnail reference then add the PLAY_VIDEO menu item to your list of menu items It's been a while since I've done any .net programming, but I'm guessing this should work.
new MenuItem() {Action = "PLAY_VIDEO", Payload = mediaLink}
An infinite load can mean the video was not the correct format or no longer is being served. I don't think this is the case here.
The video URL you mention is the same one I can get to work using Curl as documented in this answer:
Attaching video with video/vnd.google-glass.stream-url after Update XE6
(look for my answer, which is not the selected one)
This means that there is something wrong in your request, what is the response? Here is sample response when I send a working request:
{
"kind": "mirror#timelineItem",
"id": "44359ebc-ff49-4d48-a609-2f6ab1354ae3",
"selfLink": "https://www.googleapis.com/mirror/v1/timeline/44359ebc-ff49-4d48-a
609-2f6ab1354ae3",
"created": "2013-07-13T05:05:30.004Z",
"updated": "2013-07-13T05:05:30.004Z",
"etag": "\"ZECOuWdXUAqVdpmYErDm2-91GmY/h_jXHSw50TrLSr94HZGFIGAlPxs\"",
"text": "Sweetie",
"attachments": [
{
"id": "bs:9088a6e2-b8ad-4e1d-a544-5d7e858e5e3f",
"contentType": "video/vnd.google-glass.stream-url",
"contentUrl": "https://www.googleapis.com/mirror/v1/timeline/44359ebc-ff49-4d
48-a609-2f6ab1354ae3/attachments/bs:9088a6e2-b8ad-4e1d-a544-5d7e858e5e3f?alt=med
ia"
}
]
}
I just did this and do see the beep - bop video play on Glass.
So, check the response, and also see if you can print out the request, mine looks like this:
--mymultipartboundary
Content-Type: application/json; charset=UTF-8
{ "text": "Sweetie" }
--mymultipartboundary
Content-Type: video/vnd.google-glass.stream-url
http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8
--mymultipartboundary--
One way to see the request is to use a a sniffer like Charles, Fiddler or Wireshark, if that isn't working for you point your request at a php file like this then look at out.txt (note my php isn't great so you might have to modify this):
<?php
$file = 'out.txt';
$current .= print_r($_GET, true);
$current .= print_r($_POST,true);
$current .= print_r(getallheaders(),true);
file_put_contents($file, $current);
?>
I think you should focus on the second section of code you posted, it looks very close to working to me, just print out some of those items and it should be clear by comparison to my examples what is going wrong.

Apache Camel server app receiving a multipart form POST (file upload)

I'm using Camel servlet component in order to receive xml documents and now I also need to receive files (jpegs, gifs, etc). So here is how my client app is sending a file:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpClientUploadHelper {
public boolean upload(final File file, final String url) {
boolean wasSent = false ;
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
MultipartEntity entity = new MultipartEntity();
entity.addPart(file.getName(), new FileBody(file));
post.setEntity(entity);
try {
HttpResponse response = client.execute(post);
wasSent = response.getStatusLine().getStatusCode()==200;
} catch (Exception e) {
}
return wasSent;
}
}
my Camel Processor then extracts the HttpServletRequest this way:
HttpServletRequest req = exchange.getIn().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class);
then I have this method to finally parse and save the file:
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils
... class declaration, body, etc...
void parseAndSaveFile(final HttpServletRequest req) throws Exception {
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
FileItemIterator receivedFiles = upload.getItemIterator(req);
while (receivedFiles.hasNext()) {
FileItemStream file = receivedFiles.next();
if (file.isFormField()) {
System.out.println("WTF?");
} else {
String fileName = file.getName();
File uploadedFile = new File("/home/myuser/" + fileName);
FileOutputStream out = new FileOutputStream(uploadedFile);
IOUtils.copy(file.openStream(), out);
}
}
}
when I use above code within Camel, that isMultipart flag is "true" but that receivedFiles iterator doesn't contains any element. When I use above code within another project with just a plain servlet, the code works. In both ways I'm using jetty as the web container.
So is there any other way to extract the file name and it's content within my camel processor ?
Thanks!
Since you're using Jetty, have you considered using the included MultipartFilter instead of the FileUpload project? Super clean and easy to use.
From the javadoc:
"This class decodes the multipart/form-data stream sent by a HTML form that uses a file input item. Any files sent are stored to a temporary file and a File object added to the request as an attribute. All other values are made available via the normal getParameter API and the setCharacterEncoding mechanism is respected when converting bytes to Strings."
Does this help?
public void process(Exchange exchange) throws Exception {
Message in = exchange.getIn();
Set names = in.getAttachmentNames();
for(String n: names) {
System.out.println("attachment "+n);
DataHandler h = in.getAttachment(n);
if(h!=null) {
try {
Object o = h.getContent();
System.out.println(o);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
if(!names.isEmpty())
return;
}

Trying to access google places using google api client in GAE

I am trying to access google places api from appengine using code like this:
String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json";
// setup up the HTTP transport
HttpTransport transport = new UrlFetchTransport();
// add default headers
GoogleHeaders defaultHeaders = new GoogleHeaders();
transport.defaultHeaders = defaultHeaders;
transport.defaultHeaders.put("Content-Type", "application/json");
JsonHttpParser parser = new JsonHttpParser();
parser.jsonFactory = new JacksonFactory();
transport.addParser(parser);
// build the HTTP GET request and URL
HttpRequest request = transport.buildGetRequest();
request.setUrl(PLACES_DETAILS_URL);
GenericData data = new GenericData();
data.put("reference", restaurantGoogleId);
data.put("sensor", "false");
data.put("key", ApplicationConstants.GoogleApiKey);
JsonHttpContent content = new JsonHttpContent();
content.jsonFactory=new JacksonFactory();
content.data = data;
request.content = content;
try {
HttpResponse response = request.execute();
String r = response.parseAsString();
r=r;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I don't know even if this is the recommended way. If so, why this doesn't work?If I put a request in the browser directly it works, but with this code it always returns me "Request Denied".
Thanks in advance.
At the end it was easy, I mixed get and post verbs:
HttpTransport transport = new UrlFetchTransport();
// add default headers
GoogleHeaders defaultHeaders = new GoogleHeaders();
transport.defaultHeaders = defaultHeaders;
transport.defaultHeaders.put("Content-Type", "application/json");
JsonCParser parser = new JsonCParser();
parser.jsonFactory = new JacksonFactory();
transport.addParser(parser);
// build the HTTP GET request and URL
HttpRequest request = transport.buildGetRequest();
request.setUrl("https://maps.googleapis.com/maps/api/place/details/json?reference=CmRYAAAAciqGsTRX1mXRvuXSH2ErwW-jCINE1aLiwP64MCWDN5vkXvXoQGPKldMfmdGyqWSpm7BEYCgDm-iv7Kc2PF7QA7brMAwBbAcqMr5i1f4PwTpaovIZjysCEZTry8Ez30wpEhCNCXpynextCld2EBsDkRKsGhSLayuRyFsex6JA6NPh9dyupoTH3g&sensor=true&key=<APIKEY>");
try {
HttpResponse response = request.execute();
String r = response.parseAsString();

Resources