Spring MVC: After exception also 200 OK response - spring-mvc

I have below controller
#RequestMapping(value="fetchprofilepics/{profileId}/{column}/{random}",method=RequestMethod.GET)
public void fetchProfilePhoto(HttpServletResponse response, #PathVariable String profileId, #PathVariable String column, #PathVariable String random) throws IOException, ContentDeletedException
{
BufferedOutputStream bufferedOutputStream = null;
try {
//.............
bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
ByteBuffer byteBuffer = imgService.getProfilePhoto(cqlSession, column, profileId);
if(byteBuffer==null) throw new ContentDeletedException();
byte bytes[] = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes, 0, bytes.length);
bufferedOutputStream.write(bytes);
} catch (IOException ex) {ex.printStackTrace();}
finally{if(bufferedOutputStream!=null) bufferedOutputStream.close();}
throw new ContentDeletedException();
}
if byteBuffer is null it throws ContentDeletedException in tomcate log but in browser console it still show 200OK response. So in client side its showing empty image.
Why? It should not throw 200 OK status.

I found solution. I am doing this:
if(byteBuffer==null){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
else{
byte bytes[] = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes, 0, bytes.length);
bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
bufferedOutputStream.write(bytes);
}

Related

Spring MVC - Display a PDF file into web browser

I am trying to display a PDF file in a web browser with spring MVC.
public void displayActiviteFiles (Activite activite, HttpServletResponse response) throws IOException {
File file = new File(activite.getLienUploadUn());
FileInputStream inputStream = new FileInputStream(file);
IOUtils.copy(inputStream, response.getOutputStream());
response.setHeader("Content-Disposition", "attachment; filename="+file.getName());
response.setContentType("application/pdf");
response.flushBuffer();
}
But I am getting weird characters instead of the pdf content.
Where am I wrong?
To answer my question and help some others in my case, this works :
File file = new File(activite.getLienUploadUn());
FileInputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1)
{
baos.write(buffer, 0, bytesRead);
}
response.setHeader("Content-Disposition","inline; filename=\""+file.getName()+"\"");
response.setContentType("application/pdf");
ServletOutputStream outputStream = response.getOutputStream();
baos.writeTo(outputStream);
outputStream.flush();
You can display including this code.
#GetMapping(value = "/pdf")
public void showPdf(HttpServletResponse response) throws IOException {
response.setContentType("application/pdf");
InputStream inputStream = new FileInputStream(new File("/sample.pdf"));
int nRead;
while ((nRead = inputStream.read()) != -1) {
response.getWriter().write(nRead);
}
}
If it matters to anyone, then this is the 100% working solution in spring boot 1.5.11. Haven't run on manual Spring MVC projects. Maybe with some minor tweaks, can make it work.
#GetMapping(value = "/downloadFile")
public StreamingResponseBody getSteamingFile(HttpServletResponse response) throws URISyntaxException {
File file = new File(getClass().getClassLoader().getResource("templates/more/si.pdf").toURI());
//viewing in web browser
response.setContentType("application/pdf");
//for downloading the file directly if viewing is not possible
response.setHeader("Content-Disposition", "inline; filename=" + file.getName());
file = null;
//put the directory architecture according to your target directory
// generated during compilation in maven spring boot
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("templates/more/si.pdf");
return outputStream -> {
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, nRead);
}
inputStream.close();
};
}

Rxjava, Retrofit response body doesn't get the right answer?

My code like this:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
Gson gson = new GsonBuilder()
.setLenient()
.create();
this.client = new OkHttpClient.Builder().addInterceptor(logging)
.connectTimeout(25, TimeUnit.SECONDS)
.readTimeout(25, TimeUnit.SECONDS)
.build();
// retrofit with custom client
this.retrofit = new Retrofit.Builder()
.baseUrl(NetUtil.getServerBaseUrl())
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(client)
.build();
this.apiService = retrofit.create(ApiEndpoints.class);
}
public Call<String> downloadImageCall(String uri){
return apiService.rxGetImageCall(uri);
}
The retrofit is like:
#GET
Call<String> rxGetImageCall(#Url String imageUrl);
When i run my code :
String url="";
Call<String> downCall = downloadImageCall(url);
try {
Response<String> mresponse = downCall.execute();
String info =mresponse.body();
LogHelper.i("final info: "+info);
} catch (IOException e1) {
e1.printStackTrace();
}
The data returned from the server is like :
"Please contact the administrator".
However in the above code, The info is just "Please"
I am confused about it, where is wrong about my code?
Depends on #Hans answer, I changed it to Responsebody, it works. But I don't know why "Call <String>" doesn't work. Feel free to post your answer.
This is my code:
#GET
Call<ResponseBody> rxGetImageCall(#Url String imageUrl);
public Call<ResponseBody> downloadImageCall(String uri){
return apiService.rxGetImageCall(uri);
}
Call<ResponseBody> mbody = mOperation.downloadContentDetail("http://javascript.info/tutorial/hello-world");
try {
Response<ResponseBody> mResponse = mbody.execute();
InputStream mStream =mResponse.body().byteStream();
StringWriter writer = new StringWriter();
BufferedInputStream bis = new BufferedInputStream(mStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
buf.write((byte) result);
result = bis.read();
}
LogHelper.i("result 1" + buf.toString());
} catch (IOException e) {
e.printStackTrace();
}

How to get data from servlet by extjs

i create an jsonarray and sent from servlet, and sent to the front side,
the front side should get the message and currentTime, and show them in the website. How should i do that in EXTjs:
Here is the code in the servelet:
public void loadHistory(HttpServletRequest request, HttpServletResponse response) throws IOException{
JsonObject json = new JsonObject();
JsonArray dataArray = new JsonArray();
String groupName = request.getParameter("groupName");
String chatRoomName = getChatRoom(groupName);
Database db = new Database(chatRoomName);
CouchDbClient dbClient = db.getDbClient();
PrintWriter out = response.getWriter();
int i=0;
while (dbClient.contains(String.valueOf(i++))){
JsonObject objHistory = dbClient.find(JsonObject.class, String.valueOf(i++));
String preMessage = objHistory.get("message").getAsString();
String preTime = objHistory.get("currentTime").getAsString();
json.addProperty("message", preMessage);
json.addProperty("currentTime", preTime);
dataArray.add(json);
}
if (dataArray!=null){
response.setContentType("application/json");
out.print(dataArray);
out.close();
}
}
modify the below code in the if conditon before sending the response.
if (dataArray!=null){
response.setContentType("application/json");
JSONObject resultJsonMain=new JSONObject();
resultJsonMain.put("resultJsonMain",dataArray);
out.println(resultJsonMain);
out.close();
}

Tomcat returns http response code 400

I was googling for a long time, but still can't find a solution to my case.
My Tomcat sometimes returns an exception :
Error in postRequest(): Server returned HTTP response code: 400 for URL: http://localhost:80/CITIUS2/webresources/entities.personainterna/
Sometimes it works and sometimes it returns this exception, so I really don't know what is the reason...
Connection function:
public static String excutePost(String targetURL, String urlParameters) throws UnsupportedEncodingException {
URL url;
HttpURLConnection connection = null;
String responseXML = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection) url.openConnection();
byte[] requestXML = urlParameters.getBytes();
connection.setRequestProperty("Content-Length", String.valueOf(requestXML.length));
connection.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
// Send the String that was read into postByte.
OutputStream out = connection.getOutputStream();
out.write(requestXML);
out.close();
// Read the response and write it to standard out.
InputStreamReader isr = new InputStreamReader(connection.getInputStream());
BufferedReader br = new BufferedReader(isr);
String temp;
String tempResponse = "";
//Create a string using response from web services
while ((temp = br.readLine()) != null) {
tempResponse = tempResponse + temp;
}
responseXML = tempResponse;
br.close();
isr.close();
} catch (java.net.MalformedURLException e) {
System.out.println("Error in postRequest(): Secure Service Required");
} catch (Exception e) {
System.out.println("Error in postRequest(): " + e.getMessage());
}
return responseXML;
}
# Edit:
In general build is successful, there are no errors, only this one in the Apache Tomcat's output window.
Rest method:
#POST
#Consumes({"application/xml", "application/json"})
public Response create(Personainterna entity) {
try {
getJpaController().create(entity);
return Response.created(URI.create(entity.getPersonaId().toString())).build();
} catch (Exception ex) {
return Response.notModified(ex.getMessage()).build();
}
}

Write Glassfish output into servlet html page

How to redirect Glassfish server output into HttpServletResponse.out? I am making servlet in NetBeans.
here is a working example, just expose this as a servlet
public class ReadLogs extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=UTF-8";
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.append("<html>\n<head>\n\n");
out.append("<script>function toBottom()" + "{"
+ "window.scrollTo(0, document.body.scrollHeight);" + "}");
out.append("\n</script>");
out.append("\n</head>\n<body onload=\"toBottom();\">\n<pre>\n");
try {
File file = new File("C:\\pathToServerLogFile");
BufferedReader in = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
while (in.ready()) {
String x = in.readLine();
sb.append(x).append("<br/>");
}
in.close();
out.append("\n</pre>\n</body>\n</html>");
out.close();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
UPDATE
If you need to print only the last portion of the file use this after line "in.close();"
//print only 1MB Oof data
if(sb.length()>1000000){
out.append(sb.substring(sb.length()-1000000, sb.length()));
}else{
out.append(sb.toString());
}
So.. to print only lines which appeared after invoking script I've made such code:
BufferedReader reader = new BufferedReader(new FileReader("/path/to/server/log/server.log"));
int lines = 0;
while (reader.readLine() != null) {
lines++;
}
reader.close();
BufferedReader reader2 = new BufferedReader(new FileReader("/path/to/server/log/server.log"));
String strLine;
int i = 0;
while (i != lines) {
reader2.readLine();
i++;
}
while ((strLine = reader2.readLine()) != null) {
out.println(stringToHTMLString(strLine));
out.println("<br>");
}
reader2.close();
When servlet starts it counts lines in server log (saves it in variable i), then after clicking on action form it read lines which indexes are higher than i and displays it on html page. I've used function stringToHTMLString which I found somewhere on stackoverflow.
Greets.

Resources