java.io.IOException With Restful Web Service - spring

I have a weird problem with my project. When i run main method in Client to create a User after send to Server then occur fllowing error:
Exception in thread "main" java.io.IOException: Server returned HTTP
response code: 400 for URL: http://localhost:8080/rest/user/create at
sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown
Source) at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source) at
edu.java.spring.service.client.RestClientTest.createUser(RestClientTest.java:72)
at
edu.java.spring.service.client.RestClientTest.main(RestClientTest.java:30)
Here file RestClientTest.java
public class RestClientTest {
public static void main(String[] args) throws IOException{
// System.out.println("Rest Response" + loadUser("quypham"));
User user = new User();
user.setUserName("datpham");
user.setPassWord("12345");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,1960);
user.setBirthDay(calendar.getTime());
user.setAge(12);
createUser(user);
System.out.println("Rest Response" + loadUser("datpham"));
}
public static String createUser(User user) throws IOException{
URL url = new URL("http://localhost:8080/rest/user/create");
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setRequestMethod("POST");
httpConnection.addRequestProperty("Content-Type","application/json");
httpConnection.addRequestProperty("Accept","application/json");
httpConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(httpConnection.getOutputStream());
ObjectMapper mapper = new ObjectMapper();
StringWriter writer = new StringWriter();
mapper.writeValue(writer,user);
wr.writeBytes(writer.getBuffer().toString());
wr.flush();
wr.close();
return readInputStream(httpConnection.getInputStream());
}
public static String readInputStream(InputStream stream) throws IOException{
StringWriter writer = new StringWriter();
try {
int read;
byte[] bytes = new byte[4*1024];
while ((read = stream.read(bytes))!=-1) {
writer.write(new String(bytes,0,read));
}
} finally {
// TODO: handle finally clause
stream.close();
writer.close();
}
return writer.getBuffer().toString();
}
Here file UserRestServiceController.java
#Controller
public class UserRestServiceController {
#Autowired
public UserDao userDao;
#RequestMapping(value = "/rest/user/create",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.CREATED)
public void addUser(#RequestBody User user){
userDao.save(user);
}

Related

How to handle response codes in RestTemplate without catching exceptions? [Spring Boot]

I'm sending a response to another web service to create an user. If the user already exists it sends back the 409 response. I'm using RestTemplate like so:
#PostMapping("/todos/{toDoNoteId}/users")
public ResponseEntity <String> postUser(#RequestBody User user, #PathVariable int toDoNoteId, UriComponentsBuilder builder)throws HttpMessageNotReadableException, ParseException{
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://friend:5000/users";
try {
ResponseEntity<String> result = restTemplate.postForEntity(uri, user, String.class);
return result;
}
catch (HttpClientErrorException ex) {
return ResponseEntity.status(ex.getRawStatusCode()).headers(ex.getResponseHeaders())
.body(ex.getResponseBodyAsString());
}
}
While catching an exception somewhat works (in the catch block i can access the status code and body), is there a way to access it without exceptions something similar like this:
#PostMapping("/todos/{toDoNoteId}/users")
public ResponseEntity <String> postUser(#RequestBody User user, #PathVariable int toDoNoteId, UriComponentsBuilder builder)throws HttpMessageNotReadableException, ParseException{
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://friend:5000/users";
ResponseEntity<String> result = restTemplate.postForEntity(uri, user, String.class);
if(result.getStatusCode()=="409"){
// do something
}
else{
// do something else
}
return result;
}
Have you been check the ExceptionHandler? When exception throws, ExceptionHandler handles it.
For example:
#ControllerAdvice()
public class CustomExceptionHandler {
private static final Logger logger = LogManager.getLogger("CustomExceptionHandler");
#ExceptionHandler(YourException.class)
public ResponseEntity handleYourException(HttpServletRequest request, YourException ex) {
return ResponseEntity.ok("");
}
#ExceptionHandler(Exception.class)
public ResponseEntity handleException(HttpServletRequest request, Exception ex) {
logExp("Exception", request, ex);
//return new ResponseEntity<>();
return null;
}
}
You can create your own custom resttemplate and define exception handler. Here is a code snippet.
#Configuration
public class CustomRestTemplate extends RestTemplate {
#Autowired
private CustomErrorHandler customErrorHandler;
#PostConstruct
public void init() {
this.setErrorHandler(customErrorHandler);
}
}
#Component
public class CustomErrorHandler implements ResponseErrorHandler {
#Override
public boolean hasError(ClientHttpResponse response) throws IOException {
if(response.getStatusCode() != "409"){
return true;
}else {
return false;
}
}
#Override
public void handleError(ClientHttpResponse response) throws IOException {
String responseBody = response.getBody();//Pls read from InputStream and create write into String
JSONObject jsonObj = new JSONObject(result);
JSONArray jsonArray = new JSONArray();
jsonObj.put("status", response.getStatusCode());
jsonObj.put("body", responseBody );
jsonArray.put(jsonObj);
responseString = jsonArray.get(0).toString();
throw new MyException(responseString );
}
}
class MyException throw RuntimeException {
public MyException (String message) {
super(message);
}
}
So, your class will changed to
#PostMapping("/todos/{toDoNoteId}/users")
public ResponseEntity <String> postUser(#RequestBody User user, #PathVariable int toDoNoteId, UriComponentsBuilder builder)throws HttpMessageNotReadableException, ParseException{
CustomRestTemplate restTemplate = new CustomRestTemplate ();
final String uri = "http://friend:5000/users";
ResponseEntity<String> result = restTemplate.postForEntity(uri, user, String.class);
return result
}

How to redirect ftl in spring boot?

I have already created an e mail confirmation in spring boot it is working nicely, and also I created a link when a user click it should say "confirmed"but I did not figure it out how to do that?
E mail sender java class:
#Component
public class EmailSender {
#Autowired
JavaMailSender javaEmailSender;
public void sendEmail(String to, String subject, String text) throws MessagingException {
MimeMessage message = javaEmailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text, true);
helper.addInline("logo.jpg", new ClassPathResource("./images/logo.jpg"));
javaEmailSender.send(message);
}
}
E mail template Loader:
#Component
public class EmailTemplateLoader {
#Autowired
private Configuration freemakerConfiguration;
public String getEmailBody(String name, String confirmationLink) throws TemplateException {
try {
Template template = freemakerConfiguration.getTemplate("EmailConfirmation.ftl");
Map<String, Object> data = new HashMap<String, Object>();
data.put("name", name);
data.put("confirmationLink", confirmationLink);
return FreeMarkerTemplateUtils.processTemplateIntoString(template, data);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
return "";
}
}
My signup Resource :
#Autowired
private SignupService signupService;
#Autowired
private HttpServletRequest httpServletRequest;
#RequestMapping(value = "user/signup", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
#Transactional(rollbackFor = Exception.class)
public ResponseEntity<?> signup(#RequestBody UserType user) throws SignUpException {
URL requestUrl = null;
try {
requestUrl = new URL(httpServletRequest.getRequestURL().toString());
} catch (MalformedURLException e) {
logger.debug("Malformed Request Url");
}
logger.debug(requestUrl.toString());
signupService.signUp(user, requestUrl.getHost());
return new ResponseEntity<>(HttpStatus.OK);
}
#RequestMapping(value = "user/confirmation", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#Transactional(rollbackFor = Exception.class)
public ResponseEntity<?> confirmSignUp(#RequestParam("u") String loginName, #RequestParam("p") String token) {
try {
signupService.emailConfirmation(loginName, token);
return new ResponseEntity<>(HttpStatus.OK);
} catch (SignUpException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
}
So, As I told I can send an email successfully, but I could not sort how I can write confirmation successfully

Too many connection for Spring Boot Application and Apache storm

I am using spring boot application for websocket and in my storm project i am calling the spring boot application everytime to publish real time sensor data i,e per 5 minutes it is establishing 5000 connection so how to avoid this problem?
Is there any way to do connection pooling for spring boot connection in the Apache storm project?
String boot application controller class:
private static Logger logger=Logger.getLogger(GreetingController.class);
#MessageMapping("/hello")
#SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
//logger.info("+++++++Sending Greetinge+++++++" + message);
//Thread.sleep(3000); // simulated delay
return new Greeting("Hello greetings, " + message.getName() + "!");
}
#MessageMapping("/orignal")
#SendTo("/topic/orignal")
public Map<String, Object> orignal(Map<String, Object> orignal) throws Exception {
// logger.info("+++++++Sending orignale+++++++" + orignal);
//System.out.println("Sending orignal");
//Thread.sleep(3000); // simulated delay
return orignal;
}
#MessageMapping("/tupple")
#SendTo("/topic/tupple")
public Map<String, Object> tupple(Map<String, Object> tupple) throws Exception {
logger.info("+++++++Sending tupple+++++++" + tupple);
//System.out.println("Sending tupple");
//Thread.sleep(3000); // simulated delay
//String company_name=(String) tupple.get("company_name");
/*Map<String, Object> companyMap=new HashMap<String, Object>();
companyMap.put("success", true);
companyMap.put("message", "company created successfully");*/
return tupple;
}
#MessageMapping("/websocket")
#SendTo("/topic/websocket")
public Map<String, Object> websocket(Map<String, Object> websocket) throws Exception {
logger.info("+++++++Sending websocket+++++++" + websocket);
//System.out.println("Sending websocket");
//Thread.sleep(3000); // simulated delay
return websocket;
}
In storm project making connection to spring boot application:
private final static WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
public ListenableFuture<StompSession> connect(String endpoint) {
Transport webSocketTransport = new WebSocketTransport(new StandardWebSocketClient());
List<Transport> transports = Collections.singletonList(webSocketTransport);
SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.setMessageCodec(new Jackson2SockJsMessageCodec());
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
/*String url = "ws://{host}:{port}/"+endpoint;
return stompClient.connect(url, headers, new MyHandler(), "10.0.0.6", 8080);*/
String url = "ws://*************/IoTWebSocketServer-1.2.5.RELEASE/"+endpoint;
return stompClient.connect(url, headers, new MyHandler());
}
public void subscribeGreetings(String topic,StompSession stompSession) throws ExecutionException, InterruptedException {
stompSession.subscribe(topic, new StompFrameHandler() {
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
}
public void handleFrame(StompHeaders stompHeaders, Object o) {
}
});
}
public void sendHello(StompSession stompSession,String message) {
String jsonHello = "{ \"name\" : \""+message+"\" }";
stompSession.send("/app/hello", jsonHello.getBytes());
}
private class MyHandler extends StompSessionHandlerAdapter {
public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) {
}
}
public static void main(String[] args) throws Exception {
HelloClient helloClient = new HelloClient();
String endPoint = "hello";
ListenableFuture<StompSession> f = helloClient.connect(endPoint);
StompSession stompSession = f.get();
String topic= "/topic/greetings";
helloClient.subscribeGreetings(topic,stompSession);
String message = "hieeeeeeeeeeeeeeee message";
helloClient.sendHello(stompSession,message);
HelloClient helloClienttupple = new HelloClient();
String endPointtupple = "tupple";
ListenableFuture<StompSession> ftupple = helloClient.connect(endPointtupple);
StompSession stompSessiontupple = ftupple.get();
String topictupple= "/topic/tupple";
helloClient.subscribeGreetings(topictupple,stompSessiontupple);
String messagetupple = "hieeeeeeeeeeeeeeee tupple";
helloClienttupple.sendHello(stompSessiontupple,messagetupple);
JSONObject companyMap = new JSONObject();
companyMap.put("name", "Mahabali");
companyMap.put("num", new Integer(100));
companyMap.put("balance", new Double(1000.21));
companyMap.put("is_vip", new Boolean(true));
System.out.println(companyMap.toString());
stompSessiontupple.send("/app/tupple", companyMap.toString().getBytes());
//Thread.sleep(60000);
}
This the connection establishing code:
t
ry{
logger.info("++++Websocket Gateway packet++++" + topicId);
JSONObject jsonObject=new JSONObject();
JSONObject jsonObject1=new JSONObject();
JSONArray array=new JSONArray();
jsonObject.put("MAC_IMEI", topicId);
jsonObject.put("TIME", eventTime);
jsonObject.put("DEVICE", "GATEWAY");
jsonObject.put("GATEWAY", nJsonArray);
array.put(jsonObject);
jsonObject1.put("GATEWAY", array);
HelloClient helloClientwebsocket = new HelloClient();
String endPointwebsocket = "websocket";
ListenableFuture<StompSession> fwebsocket = helloClientwebsocket.connect(endPointwebsocket);
StompSession stompSessionwebsocket = fwebsocket.get();
String topicwebsocket= "/topic/websocket";
helloClientwebsocket.subscribeGreetings(topicwebsocket,stompSessionwebsocket);
stompSessionwebsocket.send("/app/websocket", jsonObject.toString().getBytes());
}
catch(Exception e)
{
logger.info("Gateway exception");
logger.error("++++Exception caught during sending the sensor details in the new websocket server++++"+e);
}

Spring Resful Client with RestTemplate

I'm using RestTemplate class to get All user but when i run Main in Client then occur error, i don't know why ???
Exception in thread "main" java.lang.ClassCastException:
java.util.LinkedHashMap cannot be cast to
edu.java.spring.service.user.model.User at
edu.java.spring.service.client.RestClientTest.main(RestClientTest.java:33)
Here file RestClientTest.java
public class RestClientTest {
public static void main(String[] args) throws IOException{
List<User> users = getUsers();
for (int i = 0; i < users.size(); i++) {
System.out.println("Rest Response" + loadUser(users.get(i).getUserName()));
}
}
public static List<User> getUsers(){
String uri = new String("http://localhost:8080/rest/user/list");
RestTemplate rt = new RestTemplate();
return (List<User>) rt.getForObject(uri,List.class);
}
public static String loadUser(String username) throws IOException {
String url = "http://localhost:8080/rest/user/json/" + username;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
InputStream stream = con.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
Here file UserRestServiceController.java
#Controller
public class UserRestServiceController {
#Autowired
public UserDao userDao;
#Autowired
public View jsonTemplate;
#RequestMapping(value = "/rest/user/list", produces = MediaType.APPLICATION_JSON_VALUE,method = RequestMethod.GET)
public #ResponseBody List<User> getUsers(){
return userDao.listUsers();
}
#RequestMapping(value="/rest/user/json/{username}")
public ModelAndView loadUser(#PathVariable("username")String name){
return new ModelAndView(jsonTemplate,"data",userDao.loadUser(name));
}
I believe the following method is not returning as you expect:
rt.getForObject(uri,List.class);
Take a look at this question as it might help you also fix your error.
ClassCastException: RestTemplate returning List instead of List

Spring deferredResult performance issue with Okhttp

I'm trying to test a basic blocking and non-blocking API controller that stream OkHttp response like following:
#SpringBootApplication
public class HttpProxyServiceApplication {
public static void main(String[] args) {
SpringApplication.run(HttpProxyServiceApplication.class, args);
}
#Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient();
}
#RestController
#RequestMapping(path = "/test")
public static class TestController {
private static final String URL = ...;
#Autowired
private OkHttpClient client;
#RequestMapping(method = RequestMethod.GET, path = "blocking")
public void blocking(HttpServletResponse httpServletResponse) throws IOException {
Request request = new Request.Builder()
.url(URL)
.build();
try (ResponseBody body = client.newCall(request).execute().body()) {
StreamUtils.copy(body.byteStream(), httpServletResponse.getOutputStream());
}
}
#RequestMapping(method = RequestMethod.GET, path = "non-blocking")
public DeferredResult<ResponseEntity<?>> nonBlocking() {
Request request = new Request.Builder()
.url(URL)
.build();
DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
ResponseEntity<Void> responseEntity =
new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
deferredResult.setResult(responseEntity);
}
#Override
public void onResponse(Response response) throws IOException {
ResponseEntity<InputStreamResource> responseEntity =
new ResponseEntity<>(new InputStreamResource(response.body().byteStream()),
HttpStatus.ACCEPTED);
deferredResult.setResult(responseEntity);
}
});
return deferredResult;
}
}
}
Important thing: I want to stream result ! I don't want to save whole result in memory. That's why for non-blocking I created a ResponseEntity<InputStreamResource>.
However using basic JMeter script that crawls on both API, the non-blocking is really slower than the blocking one
500 threads
Blocking result:
Non-blocking result:
There is any reason?
Update 1:
New test
#RequestMapping(method = RequestMethod.GET, path = "non-blocking-2")
public DeferredResult<InputStreamResource> nonBlockingBlocking() throws IOException {
Request request = new Request.Builder()
.url(URL)
.build();
DeferredResult<InputStreamResource> deferredResult = new DeferredResult<>();
deferredResult.setResult(new InputStreamResource(client.newCall(request).execute().body().byteStream()));
return deferredResult;
}
As similar result as full blocking. So I don't think is performance issue directly come from DeferredResult.

Resources