How can I check if my server is UP or DOWN in SpringMVC or just simple in JAVA?
I want a simple function how receiving a URL as a parameter and return just one boolean variable TRUE or FALSE which represents a SERVER.
#RestController
public class HealthCheckController {
#RequestMapping("/healthcheck")
public Greeting greeting() {
return "up";
}
}
When you have to check if the server is up just send get request to /healthcheck. If it returns "up", you're OK.
If you use Spring Boot, you can take a look at actuator. It allows this functionality out of the box plus some other stuff like datasource checking and so on
Related
I use React for fronted + Java Spring controllers that have some endpoints for backend. But for some of endpoints I have response with React features and for some without React features. I am new with React part, so I suppose that I am missing some principles of fetch(). Please help me to understand and fix.
Case 1
App.js code:
import React, {useState, useEffect} from 'react';
import './App.css';
function App () {
const [message, setMessage] = useState("");
useEffect(() => {
fetch('http://localhost:8080/api/v1/hello')
.then(response => response.text())
.then(message => {
setMessage(message);
});
},[])
return (
<div className="App">
<header className="">
<h1>React is here!</h1>
<h2 className="App-title">{message}</h2>
</header>
</div>
)
}
export default App;
Java controller code:
#RestController
#CrossOrigin
#RequestMapping(path = "/api/v1")
public class BasicController {
#GetMapping("/hello")
public String sayHello() {
return "Hello Everyone !";
}
}
As a result I see "React is here!" + "Hello Everyone !" with according style string on localhost:8080. So I see that the backend returns value and React also works with it.
But if I go to localhost:8080/api/v1/hello, I see only "Hello Everyone !" string without React features. So the backend returns value, but React doesn't work.
Why, if I am fetching this particular endpoint? - Question 1
Actually, the same result if I use
#RequestMapping(path = "api/v1")
without the first /
Case 2
I have the same App.js but change fetch(URL) to
fetch('http://localhost:8080')
And I add a new Controller:
#RestController
#CrossOrigin
#RequestMapping(path = "/")
public class StartPageController {
#GetMapping()
public String startPage() {
return "Start page";
}
}
If I go to localhost:8080, that I am fetching I see only "Start page" string without React features. So the backend returns value, but React doesn't work.
Why, if it is the simplest option for endpoint path and even more complex fetch worked as I mentioned above? - Question 2
Case 3
As it seems that I have some issue with "/" endpoint, I decided to check how the Case 1 endpoint will work if I leave StartPageController from the Case 2. So I just return back url:
fetch('http://localhost:8080/api/v1/hello'),
but leave both controllers.
As a result, for now, I see that React features doesn't work either for localhost:8080, or localhost:8080/api/v1/hello (the last one actually as in Case 1). Only backend values "Start page" or "Hello Everyone !" return for all mentioned endpoints. Without React.
So it seems that the "/" endpoint from StartPageController doesn't work with React by itself and also doesn't allow to work other more complex endpoints as a root endpoint.
So 2 questions as a result:
What is the issue with some particular paths - Case 1?
What is the issue with "/" endpoint - Case 2 and 3?
How I run Spring boot + React - I make a .jar file by Maven, where I collect both parts for frontend and backend by .pom build configurations. And I run the .jar in Intellij IDEA. I need to do it this way because I want to deploy .jar later on AWS Elastic Beanstalk.
Let's understand this code first :
#RestController
#CrossOrigin
#RequestMapping(path = "/api/v1")
public class BasicController {
#GetMapping("/hello")
public String sayHello() {
return "Hello Everyone !";
}
}
Probably your backend server is running at port 8080 and if you hit this url localhost:8080/api/v1/hello , it gives the output as "Hello Everyone" which you've returned from the controller right ? How do you expect to get React Part when you hit this endpoint ? When you run localhost:8080/api/v1/hello this is Spring Part [Java part] and not the react part. If you use this endpoint from the react app or any client you'll always get "Hello Everyone" as per your logic, same applies for the StartPage controller as well.
Try to run your react application, if you're fetching correctly, you'll see the backend part used with front end part. It's as simple as that.
See which port the react application is using ? It's probably localhost:3000 see if it's working or not. There, you'll see the result.
Hope this helps :)
I am switching routes in my react app using -
<Route path="/myBootDomain" render={props => {
//check route path
const onpathA = window.location.href.indexOf('/pathA') !== -1;
const onpathB = window.location.href.indexOf('/pathB') !== -1;
if (onpathA){ return <PathAComponent />;}
else if(onpathB){ return <onpathBComponent />;}
}}/>
When I run the app on localhost it works as expected, so I want my controllers to map the subdomain's to the correct route, example controller -
#CrossOrigin(maxAge = 3600)
#RestController
#RequestMapping("/pathA")
public class WebContentController {
#RequestMapping(method = RequestMethod.GET)
public void method(HttpServletRequest request, HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", "/myBootDomain/pathA");
httpServletResponse.setStatus(302);
}
}
When trying to access http://localhost:8080/myBootDomain/pathA instead of redirecting to the index file I got redirected to the same controller(infinite loop).
My index.html is under /resources/static.
Thank for any help.
What you want to do is to serve same index.html file that contains scripts (React app) but from different paths, ie: /myBootDomain/pathA and /myBootDomain/pathA/foo/bar. It'll make sure that when user reloads the URL he gets the same React app which then executes routing logic. See #tashkhisi answer to get more context https://stackoverflow.com/a/62193394/906265
Now it depends how the server app is set up and which paths you want to make "catch-all" but there was a similar question already Spring catch all route for index.html
The way React works with route is different from something you might have worked before with server side frameworks like JSF, PrimeFaces and other simmilar frameworks.
Generally in React all routing is handled in client side(at least it should be done this way) and this approach is called single page application because you have one page in which components will be changed based on the route you have in client side and those components communicate with server and changed their content based on response they are delivered with server. Here you are handling your routing in client side with <Route> Component and in browser when path changed to /pathA, PathAComponent will be rendered and no request is sent to the server in this situation because React is controlling everything here). You should design your PathAComponent in such a way when it is rendered it call your method in the backend with Http Rest call and do something based on the response (for instance show status code of response to user).
check this link for further discussion
the more clear way to do something you want to do is shown bellow:
class App extends Component {
render() {
return (
<Router>
<Switch>
<Route path='/pathA' exact={true} component={PathAComponent}/>
<Route path='/pathB' exact={true} component={PathBComponent}/>
</Switch>
</Router>
)
}
}
here when path change to /pathA in client side PathAComponent will be rendered and when path changed to /pathB component PathBComponent will be rendered. no request send to server up to this point to communicate with server you should call your REST api directly in your PathAComponent and PathBComponent, generally in componentDidMount method of your components.
class PathAComponent extends Component {
constructor(props) {
super(props);
this.state = {status: false, isLoading: true};
}
componentDidMount() {
this.setState({isLoading: true});
fetch('/myBootDomain/pathA')
.then(response => this.setState({status: response.status, isLoading: false}));
}
render() {
return (
<div>
statusCode: {status}
</div>
);
}
}
Basically, what I'm trying to achieve is something like this
#GetMapping("domain.xyz")
public String getHomepage() {
[...]
return "homepage/main.html";
}
#GetMapping("something.domain.xyz")
public String getSubdomainHomepage() {
[...]
return "homepage/subdomain.html";
}
Both domain.xyz and something.domain.xyz are pointed to the same server and the Spring app then considers the subdomain when routing so I can have different content on the top level domain and different content on the subdomain(s)...
Is this possible to achieve with Spring Boot?
(Note: This is not 100% tested, but will probably work)
I'm assuming you are having an Nginx or Apache in front of your Spring Boot application.
With Nginx for example, you would use the proxy_pass directive and then set the "Host" header to your "something.domain.xyz" or "domain.xyz" when forwarding to your Spring Boot app.
You could therefore enhance your GetMappings to filter for the Host header values.
#GetMapping(value ="/", headers="Host=domain.xyz")
public String getHomepage() {
[...]
return "homepage/main.html";
}
#GetMapping(value ="/", headers="Host=something.domain.xyz")
public String getSubdomainHomepage() {
[...]
return "homepage/subdomain.html";
}
I'm using Spring Cloud's Zuul to proxy some API requests to a few external servers. The proxying itself works well, but each service requires a (different) token provided in the request header.
I've successfully written a simple pre filter for each token that applies the appropriate header. However, I now have a problem. Even after pouring through the documentation, I can't figure out how to make each filter apply only to the proper route. I don't want to perform url-matching as the url changes across environments. Ideally, I'd have some way to get the name of the route in the filter.
My application.yml:
zuul:
routes:
foo:
path: /foo/**
url: https://fooserver.com
bar:
path: /bar/**
url: https://barserver.com
Ideally I'd like to do something like this in FooFilter.java (a prefilter):
public bool shouldFilter() {
return RequestContext.getCurrentContext().getRouteName().equals("foo");
}
but I can't seem to find any way to do this.
You can use proxy header in RequestContext to distinguish routed server like below. If you are using ribbon, you can also use serviceId header. But if you specify url direclty like above your example, you should use proxy header. One thing you have to know is that proxy header is set in PreDecorationFilter, so your pre-filter must have bigger value of filter order than the value that PreDecorationFilter has (it is 5 at this moment).
#Override
public int filterOrder() {
return 10;
}
#Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
if ((ctx.get("proxy") != null) && ctx.get("proxy").equals("foo")) {
return true;
}
return false;
}
i would like to redirect a request something like this
localhost:8080 /firstSpringProject/{uniqueusername}
to a specific controller named 'profile':
#RequestMapping(value="/profile")
public String profiles(Model model){
based on the uniqueusername i would like to render a profile page
return "profile";
}
I am using spring mvc; how can I resolve this situation is there any other way to do this?
Spring documentation says on redirect view:
Note that URI template variables from the present request are
automatically made available when expanding a redirect URL and do not
need to be added explicitly neither through Model nor
RedirectAttributes. For example:
#RequestMapping(value = "/files/{path}", method = RequestMethod.POST)
public String upload(...) {
// ...
return "redirect:files/{path}";
}
Keep in mind that version lower than 3.1.4 are affected by a memory leak due to caching redirect views.
If you are using Spring 3.1.3 or lower and you are doing this
return "redirect : profile?username="+username;
you will see OutOfMemoryError sometime.
I think you may use spring path variable here. You have to create a controller method that will take username as per your URL requirement and will redirect to profile method with username parameter.
#RequestMapping(value="/{username}")
public String getUserName(Model model,#PathVariable("username") String username){
//process username here and then redirect to ur profile method
return "redirect : profile?username="+username;
}
#RequestMapping(value="/profile")
public String profiles(Model model,String username){
//have a username and render a profile page
return "profile";
}
Thank you