I am trying to retreive byte[] from my Mono but using getBytes() method it shows unhandled IOException. How do I handle it in my reactive code?
My service layer
public HttpStatus excel(Mono<MultipartFile> filePartMono) {
Excel t = new Excel();
t.setExcel(filePartMono.map(filepart-> {
try {
return filepart.getBytes();
} catch (IOException e) {
System.out.println(e);
}
return new **byte[];** //doing this here it shows array initializer expected what does it mean
}));
excelRepository.save(t);
return HttpStatus.ACCEPTED>;
Related
I have a web application (Maven project, JSP/SERVLET, TomCat 8.5.20). The application run perfectly in localhost (same TomCat version), but when i deploy to a live server, the following code doesn't work, the 'x01Json' (JSONObject) variable value be 'null' after i cal the transfromGameToJson() method.
Game init servlet, where i set JSON in request
X01Game x01Game = gameController.initX01Game(type, legsNumber, setsNumber, users, doubleIn, doubleOut, x01,
randomOrder, startingPoint);
JSONObject x01Json = gameController.transfromGameToJson(x01Game);
session.setAttribute("x01Game", x01Game);
request.setAttribute("x01Json", x01Json);
request.getRequestDispatcher("/darts/x01game.jsp").forward(request, response);
the method
public JSONObject transfromGameToJson(X01Game x01Game) {
ObjectMapper mapper = new ObjectMapper();
try {
mapper.writeValue(new File("x01Game.json"), x01Game);
JSONObject object = new JSONObject(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(x01Game));
return object;
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
If i delete this line from my method, it's working:
mapper.writeValue(new File("x01Game.json"), x01Game);
When I want just to add more context to any exception that has happened (including parsing errors and even out of memory) I write code as follows
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
This works fine, but I may end up with OutOfMemoryError being wrapped in IllegalStateException which doesn't sound right, as further there could be dedicated exception handling mechanism just for Error throwables.
Is there any way to just add more context to exception and still preserve its original type or category? I.e. when I get OOME, I want to rethrow Error, when I get some parsing exception, I want to rethrow some unchecked exception etc. And of course I don't want to do it manually for each category, as OOME is pretty unlikely and I don't want to produce special code for corner cases (while still I want to be technically correct).
You can definitely do this in groovy by using its metaprogramming features. In particular, for your case metaclasses provides everything you need. Using them you can dynamically add/attach a contextData object to the exception you want it to carry around:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
Then to retrieve this contextData in other parts of the code, just inspect the exception object like this:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
There I am using the argument contextDataHandler as a groovy Closure to handle contextData in a flexible manner.
The following is a full working demo of this:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
Complete code on GitHub
Hope this helps.
In my custom exception middleware, I want to get exceptions processed and return the same resource with a user friendly message.
E.g When Account/Add throws an SqlException, I return Account/Add response with a message which stored in TempData from exception middleware. I already
got these view engine things done.
I found this extension method and usage for this purpose, with this, you can return all IActionResult implementations from middleware, great extension.
However, I could not find out how to return my conventional view that resides in my views folder such as Views/Account/Add
Exception Middleware
private readonly RequestDelegate _next;
public ExceptionHandler(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
HandleException(context, ex);
}
}
private void HandleException(HttpContext context, Exception exception)
{
//handle exception, log it and other stuff...
//....
var result = new ViewResult
{
ViewName = context.Request.Path.ToString(),
};
//WithDanger is an extension method writes message to tempdata
result.WithDanger("Error", exception.ToString());
//Extension method
context.WriteResultAsync(result);
}
This is what I tried but it is not working as I expected, it returns a blank page, it seems it does not make the razor view engine run to build my request page.
How can I make my middleware to return a ViewResult with my existing view properley?
There's a couple of things missing. In order to return a view using a relative path, you need to trim off the leading slash:
ViewName = context.Request.Path.ToString().TrimStart('/')
You're also not awaiting the WriteResultAsync call. Change it to something like
private TaskHandleException(HttpContext context, Exception exception)
{
//handle exception, log it and other stuff...
//....
var result = new ViewResult
{
ViewName = context.Request.Path.ToString().TrimStart('/'),
};
//WithDanger is an extension method writes message to tempdata
result.WithDanger("Error", exception.ToString());
//Extension method
return context.WriteResultAsync(result);
}
And make sure you await the call to HandleException:
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
await HandleException(context, ex);
}
}
That should work :)
I am creating a bean processor and setting setStrictHeaderValidationEnabled to true. Now my CsvParserSettings are consuming this bean processor which in turn is consumed by CSVRoutines. But on iterating through csvroutines the bean processor does not validate headers and subsequent rows get converted to beans for files with invalid headers as well
Sample Code-
final BeanProcessor<TestBean> rowProcessor = new BeanProcessor<TestBean>(TestBean.class) {
#Override
public void beanProcessed(TestBean bean, ParsingContext context) {
}
};
rowProcessor.setStrictHeaderValidationEnabled(true);
final CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(rowProcessor);
parserSettings.setHeaderExtractionEnabled(true);
parserSettings.getFormat().setDelimiter(',');
CsvRoutines routines = new CsvRoutines(parserSettings);
for(TestBean bean : routines.iterate(TestBean.class, inputFile, StandardCharsets.UTF_8)) {
try {
System.out.println(OBJECT_MAPPER.writeValueAsString(bean));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Note: TestBean uses #Parsed annotation of univocity to set column names.
The iterate method returns a IterableResult, which provides you the ParsingContext from which you can get the headers parsed from the input.
Try this code:
IterableResult<TestBean, ParsingContext> iterableResult = routines.iterate(TestBean.class, inputFile, StandardCharsets.UTF_8);
ResultIterator<TestBean, ParsingContext> iterator = iterableResult.iterator();
ParsingContext context = iterator.getContext();
String[] headers = context.headers();
//HEADERS HERE:
System.out.println(Arrays.toString(headers));
while(iterator.hasNext()){
try {
System.out.println(OBJECT_MAPPER.writeValueAsString(iterator.next()));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Hope it helps
I stumbled over this problem. Lets say i have an Func1 which parses some json string and returns the ServerState (Enum). For some reason the state cant be unknown by the Client or the JSON is bad for some reason.
How do i propagate the Exception from call Method ?
public static class ParseProgressFunction implements Func1<String, Observable<ServerState>> {
#Override
public Observable<ServerState> call(String progress) {
try {
final ServerState serverState = ServerParser.parseProgress(progress);
} catch (JSONException e) {
e.printStackTrace();
} catch (UnknownServerStateException e) {
e.printStackTrace();
}
}
}
This is the Idea i like to implement this:
#Override
public void onReceiveServerState(final Observable<String> state) {
state.flatMap(new ParseProgressFunction());
There must be some best practice, right ?
Happy Easter
As your function return an Observable, you can return a new error Observable with your exception.
return Observable.error(you exception);