Jersey & Spring Boot turns non-ok response statuses to 404 - jersey

I am using Jersey with Spring Boot 1.2.5. I have a Jersey controller (annotated with #Produces(MediaType.APPLICATION_JSON)) which works fine and returns JSON as long as I return an ok response such as
return Response.ok(dto).build();
but whenever I try to return a custom error status such as
return Response.status(Status.CONFLICT).build();
it gets turned into a 404 such as
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Error 404 Not Found</title>
</head>
<body>
<h2>HTTP ERROR 404</h2>
<p>Problem accessing /error. Reason:
<pre> Not Found</pre>
</p>
<hr>
<i>
<small>Powered by Jetty://</small>
</i>
<hr/>
</body>
</html>
Any ideas what's going on here?

Jersey expects the response to contain an entity. If I return an empty map together with my error code, the error gets passed onto the browser with an empty JSON object.
return Response.status(Status.CONFLICT).entity(new HashMap<>()).build();
If you have any better solutions, please feel free to comment.

Related

Spring Boot AJAX call API

I tried write code for ajax call api from controller. I want ajax get content of link api. I have trouble write code ajax. Please help me write this code with ajax
RestController.java
#Responsebody
#GetMapping("api/hello")
public String hello (){
return "Hello World";
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<button type="submit" name ="clickPost"></button>
</body>
</html>
I want when I click button, website return strings Hello World. Please help me write code ajax execute this request, i'm newbie. If my code controller has error, please change it help me. Thanks
Your RestController.java is fine (only missing '}' ). There is actualy no ajax call from your index.html.
It can look somethink like that:
<!DOCTYPE html>
<html>
<head>
<script>
function callAPI() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText)
}
};
xhttp.open("GET", "/api/hello", true);
xhttp.send();
}
</script>
</head>
<body>
<button onClick="callAPI()">Click me</button>
</body>
</html>
Depending on your particular environment you still might need to update the API URL in javascript or enabling CORS. Check these links
https://web.dev/cross-origin-resource-sharing/
https://spring.io/guides/gs/rest-service-cors/

How to view data retrieved in the controller in the view?

I'm trying to retrieve data in my controller using sqlsrv database connection and I want to view the result in my test.blade.php
public function index()
{
$cout_achat = DB::table('[DWH_SOVAC_PROD_KIT_LIFE_CYCLE]')
->select( DB::raw('SUM([MONTANT_LC]) as cout_achat'))
->get();
return view('test', ['test' => $cout_achat]);
}
and the code in the view
<html lang="{{ config('app.locale') }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600"
rel="stylesheet" type="text/css">
</head>
<body>
echo {{$cout_achat}};
</body>
</html>
but when I try to access myapp/test I get : ** Use of undefined constant test - assumed 'test' (this will throw an Error in a future version of PHP) (View: C:\wamp64\www\projetSovac\resources\views\test.blade.php) –**
About 404 the route you have provided is completely ok, can you please tell us how you are calling this route.
And please double check any typo in controller name.
Now I would like to talk about some improvement in your code
First of all is that when you return the view like this in your controller
return view('test', ['test' => $cout_achat]);
The $cout_achat will be available with name $test in your blade file. So you should try to use the same naming convention like
return view('test', ['cout_achat' => $cout_achat]);
Or simple you can use compact() laravels helper function like this
return view('test', compact(cout_achat));
It will automatically pass $cout_achat in blade.
Now for echoing the variable in balde you don't need to use echo explicitly like
echo {{$cout_achat}};
You can echo variables like
{{$cout_achat}}
Anything else will be handled automatically by blade compiler.
Hope this will help.

Get Raw Html From the controller Spring thymeleaf

I have a controller that create model attribute and passes to the view "partial.html" to generate output
partial.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home page</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<p>
<span th:text="'Today is: ' + ${message}"></span>
</p>
</body>
</html>
and inside a controller method
model.addAttribute("message", search);
How to do I get Htlm Output to a string inside controller method?
like this
String htmlOutput="from partial.html";
Let's say you have a HTML file with two variable name and todayDate.
You want to process it and want to store it in a string / database / AWS S3.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<p>Hello</p>
<p th:text="${name}"></p>
<p th:text="${todayDate}"></p>
</body>
</html>
Your HTML file location is src/main/resources/templates/home.html
By using the below function you can get the final processed HTML as:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<p>Hello</p>
<p>Manoj</p>
<p>30 November 2019</p>
</body>
</html>
import org.thymeleaf.context.Context;
#GetMapping("/")
public void process() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML");
// https://github.com/thymeleaf/thymeleaf/issues/606
templateResolver.setForceTemplateMode(true);
templateEngine.setTemplateResolver(templateResolver);
Context ctx = new Context();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
Calendar cal = Calendar.getInstance();
ctx.setVariable("todayDate", dateFormat.format(cal.getTime()));
ctx.setVariable("name", "Manoj");
final String result = templateEngine.process("home", ctx);
System.out.println("result:" + result);
}
If you're using the usual Spring MVC approach, as Joanna says you're doing things in the wrong order. The Controller creates the model and specifies the view, and then after that the view is rendered by the Thymeleaf template that uses the model.
If, on the other hand, you're trying to render Thymeleaf templates yourself (rather than sending them to the user's browser directly, maybe for use in HTML email or to store prerendered pages in a database or something), then you'd need to create your own Thymeleaf Template Engine to use. Refer to the "Creating and configuring the Template Engine" section of the documentation for details. You can create your own Engine, and then use its process method to get the result of the template to put into a variable for further use.
You may looking for this, getting directly the result HTML, just ignore the email part of the post.
Then, you can create this:
final Context ctx = new Context(locale);
ctx.setVariable("name", recipientName);
ctx.setVariable("subscriptionDate", new Date());
ctx.setVariable("hobbies", Arrays.asList("Cinema", "Sports", "Music"));
ctx.setVariable("imageResourceName", imageResourceName);
// so that we can reference it from HTML
final String htmlContent = this.templateEngine.process("html/email-inlineimage.html", ctx);
So you have the htmlContext of rendered thymeleaf template (with vars)
Once the control goes out to view processor (JSP/Thymeleaf etc), it will not be coming back to controller. You will be able to get the raw html response in a customFilter, but not in the Controller.

Read/write to Parse Core db from Google Apps Script

I'm just starting to use Parse Core (as Google'e ScriptDB is being decommissioned soon) and am having some trouble.
So I'm able to get Parse Core db to read/write using just a standard HTML page as shown below:
<!doctype html>
<head>
<meta charset="utf-8">
<title>My Parse App</title>
<meta name="description" content="My Parse App">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/styles.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.2.18.min.js"></script>
</head>
<body>
<div id="main">
<h1>You're ready to use Parse!</h1>
<p>Read the documentation and start building your JavaScript app:</p>
<ul>
<li>Parse JavaScript Guide</li>
<li>Parse JavaScript API Documentation</li>
</ul>
<div style="display:none" class="error">
Looks like there was a problem saving the test object. Make sure you've set your application ID and javascript key correctly in the call to <code>Parse.initialize</code> in this file.
</div>
<div style="display:none" class="success">
<p>We've also just created your first object using the following code:</p>
<code>
var TestObject = Parse.Object.extend("TestObject");<br/>
var testObject = new TestObject();<br/>
testObject.save({foo: "bar"});
</code>
</div>
</div>
<script type="text/javascript">
Parse.initialize("PyMFUxyBxR8IDgndjZ378CeEXH2c6WLK1wK2JHYX", "IgiMfiuy3LFjzH0ehmyf5Rkti8AmVtwcGqc6nttN");
var TestObject = Parse.Object.extend("TestObject");
var testObject = new TestObject();
testObject.save({foo: "bar"}, {
success: function(object) {
$(".success").show();
},
error: function(model, error) {
$(".error").show();
}
});
</script>
</body>
</html>
However, when I try to serve that up using the HtmlService shown below, I get no response from Parse. Parse Core.html basically has all of the code I have above ( only thing I changed was to remove the css calls).
function doGet() {
var htmlPage = HtmlService.createTemplateFromFile('Parse Core.html')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE)
.setTitle('Parse Core Test');
return htmlPage;
}
Link to ParseDb Library for Apps Script
Here is the key to add the library: MxhsVzdWH6ZQMWWeAA9tObPxhMjh3Sh48
Install that library and it allows you to use most of the same methods that were used by ScriptDb. As far as saving and querying go they almost identical. Make sure to read the Library's notes, how to add the applicationId and restApiKey. It is a little different that you can silo data by classes which must be defined in the call to Parse.
Bruce here is leading the way on database connection for Apps Script, he has plenty of documentation on using Parse.com, and also his own DbConncection Drive that would allow you to use a number of back-end systems.
Excel Liberation - Bruce's Site.

Ajax using <g:remoteLink> in Grails

Reading through the Grails docs (see here http://grails.org/doc/latest/guide/theWebLayer.html#ajax), I was led to believe that I could use Ajax to update a div using the following syntax:
My view (Ajax/index.gsp)
<!doctype html>
<head>
<meta name="layout" content="main"/>
</head>
<body>
<div id="error"></div>
<div id="message"></div>
<g:remoteLink action="retrievePets" update="message">Ajax magic... Click here</g:remoteLink>
</body>
</html>
My controller (AjaxController):
package genericsite
class AjaxController {
def index() { }
def retrieveMessage() {
render "Weeee! Ajax!"
}
}
However, when I select the link, it just sends me to a page with "Weeee! Ajax!" I know how to do this the typical jQuery way. This is slightly more convenient...
The default "main" layout doesn't include a javascript library by default, so if you want to use remoteLink or any of its associates you'll need to add
<r:require module="jquery"/>
or (if you're on a pre-2.0 version of Grails or not using the resources plugin)
<g:javascript library="jquery"/>
to the <head> section of your GSP.

Resources