how to connect to the spring-boot API from my web browser? - spring-boot

I am trying to connect to the code I have wrote through my browser, but unfortunately can not figure out how to do so. I have tried 127.0.0.1/hash but it did not work even though I have build the project using maven build compile. was wondering if someone could tell me what am I doing wrong here.
here is the code :
package com.snhu.sslserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
#SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
#RestController
class ServerController{
public static String calculateHash(String name) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(name.getBytes(StandardCharsets.UTF_8));
BigInteger number = new BigInteger(1, hash);
StringBuilder hexString = new StringBuilder(number.toString(16));
while (hexString.length() < 32)
{
hexString.insert(0, '0');
}
return hexString.toString();
}
#RequestMapping("/hash")
public String myHash() throws NoSuchAlgorithmException{
String data = "Hello Kamran Khosravi!";
String hash = calculateHash(data);
return "<p>data:"+data+" : SHA-256 "+" : "+hash;
}
}

you can just replace the port 8080 with respective to your port number which you have in application.properties
Command : spring-boot:run
http://localhost:8080/hash

Related

Mockito when().thenReturn doesn't give expected result

I am new to Junit and Mockito.
Trying to mock one of the object of the class, but it is not working.
The mock method is returning an empty list, due to which test case is getting failed.
This is the code which I have written.
Junit Test Class : Here I have mocked the object and method to return an Arraylist, but when the code is executed this mock method is returning an empty list due to which test case is getting failed.
package com.business;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import com.data.api.ToDoService;
public class TodoBusinessImplMockTest {
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
#Test
public void testRetrieveTodosRelatedToSpringUsingMock()
{
ToDoService todoServiceMock = mock(ToDoService.class);
List<String> todoList=Arrays.asList("Learn Spring MVC", "Learn Spring","Learn to Dance");
Mockito.when(todoServiceMock.retrieveTodos("Dummy")).thenReturn(todoList);
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoServiceMock);
List<String> todos = todoBusinessImpl.retrieveTodosRelatedToSpring("Ranga");
assertEquals(2, todos.size());
}
}
Interface : ToDoService.java
package com.data.api;
import java.util.List;
public interface ToDoService {
public List<String> retrieveTodos(String s);
}
TodoBusinessImpl.java
package com.business;
import java.util.ArrayList;
import java.util.List;
import com.data.api.ToDoService;
public class TodoBusinessImpl {
private ToDoService todoService;
TodoBusinessImpl(ToDoService todoService) {
this.todoService = todoService;
}
public List<String> retrieveTodosRelatedToSpring(String s) {
List<String> filteredTodos = new ArrayList<String>();
List<String> allTodos = todoService.retrieveTodos(s);
for (String todo : allTodos) {
if (todo.contains("Spring")) {
filteredTodos.add(todo);
}
}
return filteredTodos;
}
}
Your spec says:
Mockito.when(todoServiceMock.retrieveTodos("Dummy")).thenReturn(todoList);
but your call uses:
todoBusinessImpl.retrieveTodosRelatedToSpring("Ranga");
"Ranga" isn't "Dummy", therefore your spec isn't matched; therefore mockito returns the default result (which would be an empty list).
Try replacing the "Dummy" in Mockito.when(todoServiceMock.retrieveTodos("Dummy")).thenReturn(todoList); with anyString() (import static org.mockito.ArgumentMatchers.anyString;). This did the trick for me.

Why does a method with return type List<String> return a JSON but return type of String return a html?

I am new to learning springboot. I have a simple #Restcontroller which has two end points /hello and /helloworld.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#SpringBootApplication
#RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#GetMapping(path = "/hello")
public String sayHelo(){
return "Hello";
}
#GetMapping(path = "/helloworld")
public List<String> sayHelloWorld(){
return List.of(
"Hello","World"
);
}
}
When I go to localhost:8080/hello I am getting the response as a html page.
But when I go to localhost:8080/helloworld the response is a JSON.
I do not understand why the first request I am getting as a html and the second as a JSON.
I was expecting a JSON in the first request as well.

convert a simple maven websocket tyrus project to javac command line

Out of curiosity I'd like to build a simple websockets tyrus server chat project with javac and libraries in -classpath.
Yes, I know that this is not the standard way (mvn is), but I'm doing it as a proof of concept. I manage to get project built but it throws a NullPointerException
Code is:
ChatMain.java:
package chat;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import javax.websocket.DeploymentException;
import org.glassfish.tyrus.server.Server;
public class ChatMain {
public static void main(String[] args) throws DeploymentException,
IOException {
Map<String, Object> properties = Collections.emptyMap();
Server server = new Server("localhost", 8080, "/ws", properties,
ChatEndPoint.class);
System.out.println(server);
try {
server.start();
System.in.read();
} finally {
server.stop();
}
}
}
ChatEndPoint.java:
package chat;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.json.*;
#ServerEndpoint("/chat")
public class ChatEndPoint {
private static Map<String, Session> peers = Collections.synchronizedMap(new HashMap<String, Session>());
#OnOpen
public void onOpen(Session peer) {
System.out.println("onOpen");
}
#OnMessage
public void onMessage(String message, Session peer) throws IOException {
System.out.println("onMessage");
JSONObject json = new JSONObject(message);
String nick = (String) json.get("nick");
boolean newClient = json.has("action") && ((String) json.get("action")).equals("add");
synchronized(peers) {
// Iterate over the connected sessions
// and broadcast the received message
for (Map.Entry<String, Session> entry : peers.entrySet()) {
if (newClient) {
JSONObject json1 = new JSONObject(json, new String[] { "action" }).put("nick", entry.getKey());
peer.getBasicRemote().sendText(json1.toString());
}
entry.getValue().getBasicRemote().sendText(message);
}
}
if (newClient)
peers.put(nick, peer);
}
#OnClose
public void onClose(Session peer) {
System.out.println("onClose");
peers.values().remove(peer);
}
}
javac line:
javac -cp chat/javax.websocket-api-1.1.jar:chat/tyrus-server-1.12.jar:chat/tyrus-spi-1.12.jar:chat/tyrus-core-1.12.jar:chat/grizzly-framework-2.3.22.jar:chat/grizzly-http-server-2.3.22.jar:chat/tyrus-container-grizzly-server-1.12.jar:chat/json.jar: chat/ChatMain.java
java line:
java -cp chat/javax.websocket-api-1.1.jar:chat/tyrus-server-1.12.jar:chat/tyrus-spi-1.12.jar:chat/tyrus-core-1.12.jar:chat/grizzly-framework-2.3.22.jar:chat/grizzly-http-server-2.3.22.jar:chat/tyrus-container-grizzly-server-1.12.jar:chat/json.jar: chat.ChatMain
runtime error:
Exception in thread "main" java.lang.NullPointerException
at org.glassfish.tyrus.container.grizzly.server.GrizzlyServerContainer$1.stop(GrizzlyServerContainer.java:228)
at org.glassfish.tyrus.server.Server.stop(Server.java:231)
at chat.ChatMain.main(ChatMain.java:23)
I understand that this can be done
Interestingly, more libraries are needed. If I include all libraries in websocket-ri-archive-1.12.zip bundle, it works well. Definitely, a builder is the way to go

Spring boot rest : Circular view path [error]: would dispatch back to the current handler URL [/error] again

My issue is I get 404 error when calling the spring boot application on localhost:8080/users
package com.myproj.users.controller;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import java.security.Principal;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.myproj.users.Greeting;
import com.myproj.users.PhysicalCharacteristicsRepository;
import com.myproj.users.UserRepository;
import com.myproj.users.UserResource;
#RestController
#RequestMapping("/users")
public class UserRestController {
private UserRepository userRepository;
private PhysicalCharacteristicsRepository characteristicsRepository;
#RequestMapping(value = "/greeting/", method = RequestMethod.GET)
public String greeting() throws UserPrincipalNotFoundException {
return "Greeting";
}
#RequestMapping(value = "/error/")
public String error() {
return "Error handling";
}
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody Greeting sayHello(#RequestParam(value = "name", required = false, defaultValue = "Stranger") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
#Autowired
UserRestController(UserRepository userRepository, PhysicalCharacteristicsRepository characteristicsRepository) {
this.userRepository = userRepository;
this.characteristicsRepository = characteristicsRepository;
}
}
package com.myproj.users.controller;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import org.springframework.hateoas.VndErrors;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.weather.exceptions.UserNotFoundException;
#ControllerAdvice
class UserControllerAdvice {
#ResponseBody
#ExceptionHandler(UserNotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
VndErrors userNotFoundExceptionHandler(UserNotFoundException ex) {
return new VndErrors("error", ex.getMessage());
}
#ResponseBody
#ExceptionHandler(UserPrincipalNotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
VndErrors userPrincipalNotFoundException(UserPrincipalNotFoundException ex) {
return new VndErrors("error", ex.getMessage());
}
}
package com.myproj.users;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
I have tested the spring project in https://spring.io/guides/gs/actuator-service/ and it worked so I ignore what's going on.
I have defined a controller to manage errors. I have copied it from Spring Boot Remove Whitelabel Error Page
The new Application class is the following :
package com.test;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#Configuration
#ComponentScan(basePackages = "com.test")
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
public class Application {
static final Logger logger = LogManager.getLogger(Application.class.getName());
public static void main(String[] args) {
logger.debug("Entered the application");
SpringApplication.run(Application.class, args);
}
private Application() {
}
}
As you can see I have added a controller in ComponentScan as follows :
#ComponentScan(basePackages = "com.test")
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
To test I used curl curl http://localhost:9002/eleves/Hammami/ and firefox.
Changing #Controller to #RestController solved my issue.
In my case I was using thymeleaf(MVC), after that I switched to pure backend.

How does one override this `/error` endpoint?

I am studying Spring OAuth by decomposing this set of three interconnected apps at GitHub, while also carefully studying the Spring OAuth 2 Developer Guide at this link. The Developer Guide says that the /oauth/error endpoint needs to be customized, but what specific code should be use to accomplish a successful override of /oauth/error?
FIRST ATTEMPT:
My first attempt at doing the override, is throwing errors, which you can see in the debug log, which I have uploaded to a file sharing site at this link.
I started by trying to get code elements provided by Spring to work in the sample app.
First, I added a new controller class to the authserver app in the sample app link above, and I added some of the sample code from Spring's WhiteLabelErrorEndpoint.java, which you can read at this link. My attempt is as follows:
package demo;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.HtmlUtils;
#Controller
public class CustomViewsController {
private static final String ERROR = "<html><body><h1>OAuth Error</h1><p>${errorSummary}</p></body></html>";
#RequestMapping("/oauth/error")
public ModelAndView handleError(HttpServletRequest request) {
Map<String, Object> model = new HashMap<String, Object>();
Object error = request.getAttribute("error");
// The error summary may contain malicious user input,
// it needs to be escaped to prevent XSS
String errorSummary;
if (error instanceof OAuth2Exception) {
OAuth2Exception oauthError = (OAuth2Exception) error;
errorSummary = HtmlUtils.htmlEscape(oauthError.getSummary());
}
else {
errorSummary = "Unknown error";
}
model.put("errorSummary", errorSummary);
return new ModelAndView(new SpelView(ERROR), model);
}
}
And I added the following SpelView.java String handler class used by the link above by copying the code from this link:
package demo;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
/**
* Simple String template renderer.
*
*/
class SpelView implements View {
private final String template;
private final String prefix;
private final SpelExpressionParser parser = new SpelExpressionParser();
private final StandardEvaluationContext context = new StandardEvaluationContext();
private PlaceholderResolver resolver;
public SpelView(String template) {
this.template = template;
this.prefix = new RandomValueStringGenerator().generate() + "{";
this.context.addPropertyAccessor(new MapAccessor());
this.resolver = new PlaceholderResolver() {
public String resolvePlaceholder(String name) {
Expression expression = parser.parseExpression(name);
Object value = expression.getValue(context);
return value == null ? null : value.toString();
}
};
}
public String getContentType() {
return "text/html";
}
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
Map<String, Object> map = new HashMap<String, Object>(model);
String path = ServletUriComponentsBuilder.fromContextPath(request).build()
.getPath();
map.put("path", (Object) path==null ? "" : path);
context.setRootObject(map);
String maskedTemplate = template.replace("${", prefix);
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper(prefix, "}");
String result = helper.replacePlaceholders(maskedTemplate, resolver);
result = result.replace(prefix, "${");
response.setContentType(getContentType());
response.getWriter().append(result);
}
}
To override the error view define a controller, e.g.
#Controller
public class ErrorController {
#RequestMapping("/oauth/error")
public String error(Map<String,Object> model) {
// .. do stuff to the model
return "error";
}
}
and then implement the "error" view. E.g. using Freemarker, in a Spring Boot app you create a file called "error.ftl" in the "templates" directory at the top of the classpath:
<html><body>Wah, there was an error!</body></html>
This is all just vanilla Spring MVC so please refer to the Spring user guide for more details.

Resources